-
Notifications
You must be signed in to change notification settings - Fork 25
Shaping/Transforming Data #7
Comments
Based on a conversation with @maier49 and @agubler here is what I see as the main "use case" for stores and widgets when operating in a Dojo 2 application: Which the following describes the process:
|
Will the user register a pipeline, |
My feeling was that a pipeline like that would imply that it is being tracked, as that would be the most common use case, with an options to produce it as a one off. I would expect const source = store
.query({ /* query options */})
.transform({ /* transform options */);
const target = createMemoryStore();
const handle = materialize({
source,
target,
reducer(item, source, target): ChangeRecord | Promise<ChangeRecord> {
/* do whatever */
}
});
handle.destroy(); |
* Wipe out files for merging new stores. * Starting work on new store * Start conversion to use observables, and incorporate dojo-2-package template * Compiles with Memory and Request Stores commented out - WIP * Fix dependency issues with new version of grunt-dojo2 * Update some dependencies and fix folder case * Fix capitalization, make interfaces default exports * Refactoring * Make Patches and Queries have two generic parameters to express the original type as well as the resulting type. * Create a CompoundQuery class to allow for any arbitrary queries to be combined into a single query. * Remove the second generic type in BaseStore. For the most part, the type of the items in the store will not change between the source and the subStore, so they can use the same generic type. If they did change types, in one case the items could be mapped to a completely different type. In this case updates can no longer happen by delegating to the parent because there's no way to reverse engineer the relationship between the items. In the case where a selection or a similar operation has been performed, it would be useful, but the direction of the type relationship is contravariant. If the source has Items of type {a: string, b: string}, the child would have elements of either {a: string}, {a: string, b: string}, or {b: string}. In any other case we have the problem mentioned above. But in this case, the resulting item is a superclass of the source store. Which means the signature for this opertion would need to be something like ``` Store<A, B extends A> { source: Store<B> select<C extendedBy A>: Store<C, A>; } ``` But we can't express that. * Refactoring * Add more options for serialization * Move queries to their own package * Add select query * Change pointer add method to push, and add pop * Change factory names to match compose pattern * Fix testing configuration and dist build * Add a few simple unit tests for sort. * Add store 'actions', minor refactoring * Change `type` in filter to `filterType`, query already has a queryType so this is hopefully more consistent/clearer. * Add store 'actions'. They're not necessarily proper actions but they express a similar pattern. They also, with the StoreActionManager, form the start of an attempt at handling conflicts and out of date data. * Adding in "actions" Store "Actions" are meant to wrap an update and allow for * Handling conflicts and other failures gracefully * Handle ordering of concurrent requests * Use an observer instead of a promise for a single action's results Using an observer instead of a promise for a single action's result allows a lot of code passing promises through to be eliminated. It also simplified the interaction for an end user of the API, as retrying a failed request repeatedly no longer requires a potentially endless chain of promises. * Implement memory store and add some unit tests for it Also includes refactoring * Adding tests - in a broken state * More tests * Minor changes to make code compile. * Fix dojo dependency versions * Add more unit tests * Add another test for subcollections * Start adding more detailed tests for each method * bump peer deps to 'next' tag and config for UMD typings * change deps to peer deps in line with dojo2 convention, add grunt task for peer deps * update .gitignore for node_modules and .tsconfig*.json files * implement 'noImplicitThis' * Fix the build(compile) issue by switching back to previous working version of dependencies. The tsc compile issue is cased by some issue in the `next` tag of `dojo-core` package. Until a more stable version of `dojo-core` is released, we have to use previous working version for now. * Add more unit tests for MemoryStore. Fix minor code issue. Note: a few unit tests are still failing. Need to either update code to pass the unit tests, or remove the tests if we feel the tests are making wrong assumptions. * Minor API change, fixes to Actions, add method, and tests Action result 'errors' really represent data conflicts only, as other errors will still be handled through the error callback of the action. The relevant flag has been renamed to better reflect that. Action observers should only call `retryAll` or `filter` synchronously within the callback, and if they are not an appropriate error will be thrown. This is mainly so that the observer can be completed if the action is not going to be retried, by checking after its next callback whether `retryAll` or `filter` was called on the result. Actions now also throw appropriate errors when `retryAll` or `filter` is called more than once on the same result object, or on a successful result object. `Add` now calls `put` on retry, as retrying an add means that the item already exists but we want to update it anyway. Changed tests to reflect that: * Adding an existing item should be considered a data conflict, but the action should be able to be retried, and in that case it should update the existing item. * When subscribing to the store's observable, an initial update should be received that indicates the state of the store at the time of subscription. Fixes two other miscellaneous bugs: * `_add` in `MemoryStore` was adding all passed items to the store's data. Now it correctly only adds only the new items. * On retry, the action was being executed immediately instead of being queued. * Add grunt watch task registered as the default task. * Add unit tests around `store#fetch`. The factory function `rangeFactory` is changed to `createRange` to be consistent with the rest of application such as filter#createFilter etc. * fix TS2 version and bump dojo deps (#7) * Minor refactor and more tests * Minor changes to update interface so that all updates can optionally have an item or index property. This avoids a lot of casting to different update types. * Updates to track and release API so that they return a promise to the store. * Don't send out an initial update of current items when observing the store. If using fetch, it's not performant, and if not using fetch, the results can be surprising because the local data may not be what is expected at the time of observation. * Getting rid of fat arrow functions to match dojo style guide * Making the order of actions more controllable via custom store managers by adding a retry function. The default manager currently just executes the next available action asynchronously as soon as the current action executes once. Any retries on that action are treated as new actions and just queued normally. With the separate retry method an action manager could be implemented that waits until the current action is completed, including waiting for any retries. * Refactoring API and breaking out into separate compose mixins * Separate query module into a mixin. Use instance constructor as subcollection factory Make observableStoreMixin subcollection aware * Add more unit tests for query mixin * Fix query mixin so it doesn't query recursively * Adding track and release mixin - No tests yet * Add unit tests from previous code. Add unit tests for track mixin. (doesn't compile yet) Add unit tests for Patch/JsonPointer. * achieved 100% coverage. * a few issues were caught and fixed. * Interface cleanup and test case for trackable mixin Fix ordering for operations and tracking. Doesn't resolve the case where fetching occurs around the operation. * Add more test cases for and fix issues with operation ordering * Split else onto a separate line * Update readme * Fix internal link in readme * Really fix internal link in readme * Add unit tests. * Most modules has 100% coverage. * Overall coverage is over 80%, while a few corner cases are not covered yet. * Fix a few issues caught by tests. * Cleanup. * Fix build issues. * Comment out failing unit tests. See dojo/compose/#81 for details. * Add missing all.ts to fix build issue. * Switch back to previous version of compose, uncomment unit tests. * Will update accordingly based on discussion in /dojo/compose/#81 * Attempt to fix build issue by adding `Rx.config.Promise` * Fix build issues on IE 10/11 caused by unavailable functionality. * Update IOS version due to issues with saucelabs environments. * Update IOS version to 9.3 due to issues with saucelabs environments. * Trigger Build. (Previous build #32 seems to hang for no reason.) * Add more tests to cover more areas of logic. * Feedback changes: package name and version etc. * Move file into mixin dir. * Add createTransactionMixin. * Remove dtsGenerator grunt config * Add tests for createTransactionMixin. Fix issues caught by tests.
* Wipe out files for merging new stores. * Starting work on new store * Start conversion to use observables, and incorporate dojo-2-package template * Compiles with Memory and Request Stores commented out - WIP * Fix dependency issues with new version of grunt-dojo2 * Update some dependencies and fix folder case * Fix capitalization, make interfaces default exports * Refactoring * Make Patches and Queries have two generic parameters to express the original type as well as the resulting type. * Create a CompoundQuery class to allow for any arbitrary queries to be combined into a single query. * Remove the second generic type in BaseStore. For the most part, the type of the items in the store will not change between the source and the subStore, so they can use the same generic type. If they did change types, in one case the items could be mapped to a completely different type. In this case updates can no longer happen by delegating to the parent because there's no way to reverse engineer the relationship between the items. In the case where a selection or a similar operation has been performed, it would be useful, but the direction of the type relationship is contravariant. If the source has Items of type {a: string, b: string}, the child would have elements of either {a: string}, {a: string, b: string}, or {b: string}. In any other case we have the problem mentioned above. But in this case, the resulting item is a superclass of the source store. Which means the signature for this opertion would need to be something like ``` Store<A, B extends A> { source: Store<B> select<C extendedBy A>: Store<C, A>; } ``` But we can't express that. * Refactoring * Add more options for serialization * Move queries to their own package * Add select query * Change pointer add method to push, and add pop * Change factory names to match compose pattern * Fix testing configuration and dist build * Add a few simple unit tests for sort. * Add store 'actions', minor refactoring * Change `type` in filter to `filterType`, query already has a queryType so this is hopefully more consistent/clearer. * Add store 'actions'. They're not necessarily proper actions but they express a similar pattern. They also, with the StoreActionManager, form the start of an attempt at handling conflicts and out of date data. * Adding in "actions" Store "Actions" are meant to wrap an update and allow for * Handling conflicts and other failures gracefully * Handle ordering of concurrent requests * Use an observer instead of a promise for a single action's results Using an observer instead of a promise for a single action's result allows a lot of code passing promises through to be eliminated. It also simplified the interaction for an end user of the API, as retrying a failed request repeatedly no longer requires a potentially endless chain of promises. * Implement memory store and add some unit tests for it Also includes refactoring * Adding tests - in a broken state * More tests * Minor changes to make code compile. * Fix dojo dependency versions * Add more unit tests * Add another test for subcollections * Start adding more detailed tests for each method * bump peer deps to 'next' tag and config for UMD typings * change deps to peer deps in line with dojo2 convention, add grunt task for peer deps * update .gitignore for node_modules and .tsconfig*.json files * implement 'noImplicitThis' * Fix the build(compile) issue by switching back to previous working version of dependencies. The tsc compile issue is cased by some issue in the `next` tag of `dojo-core` package. Until a more stable version of `dojo-core` is released, we have to use previous working version for now. * Add more unit tests for MemoryStore. Fix minor code issue. Note: a few unit tests are still failing. Need to either update code to pass the unit tests, or remove the tests if we feel the tests are making wrong assumptions. * Minor API change, fixes to Actions, add method, and tests Action result 'errors' really represent data conflicts only, as other errors will still be handled through the error callback of the action. The relevant flag has been renamed to better reflect that. Action observers should only call `retryAll` or `filter` synchronously within the callback, and if they are not an appropriate error will be thrown. This is mainly so that the observer can be completed if the action is not going to be retried, by checking after its next callback whether `retryAll` or `filter` was called on the result. Actions now also throw appropriate errors when `retryAll` or `filter` is called more than once on the same result object, or on a successful result object. `Add` now calls `put` on retry, as retrying an add means that the item already exists but we want to update it anyway. Changed tests to reflect that: * Adding an existing item should be considered a data conflict, but the action should be able to be retried, and in that case it should update the existing item. * When subscribing to the store's observable, an initial update should be received that indicates the state of the store at the time of subscription. Fixes two other miscellaneous bugs: * `_add` in `MemoryStore` was adding all passed items to the store's data. Now it correctly only adds only the new items. * On retry, the action was being executed immediately instead of being queued. * Add grunt watch task registered as the default task. * Add unit tests around `store#fetch`. The factory function `rangeFactory` is changed to `createRange` to be consistent with the rest of application such as filter#createFilter etc. * fix TS2 version and bump dojo deps (dojo#7) * Minor refactor and more tests * Minor changes to update interface so that all updates can optionally have an item or index property. This avoids a lot of casting to different update types. * Updates to track and release API so that they return a promise to the store. * Don't send out an initial update of current items when observing the store. If using fetch, it's not performant, and if not using fetch, the results can be surprising because the local data may not be what is expected at the time of observation. * Getting rid of fat arrow functions to match dojo style guide * Making the order of actions more controllable via custom store managers by adding a retry function. The default manager currently just executes the next available action asynchronously as soon as the current action executes once. Any retries on that action are treated as new actions and just queued normally. With the separate retry method an action manager could be implemented that waits until the current action is completed, including waiting for any retries. * Refactoring API and breaking out into separate compose mixins * Separate query module into a mixin. Use instance constructor as subcollection factory Make observableStoreMixin subcollection aware * Add more unit tests for query mixin * Fix query mixin so it doesn't query recursively * Adding track and release mixin - No tests yet * Add unit tests from previous code. Add unit tests for track mixin. (doesn't compile yet) Add unit tests for Patch/JsonPointer. * achieved 100% coverage. * a few issues were caught and fixed. * Interface cleanup and test case for trackable mixin Fix ordering for operations and tracking. Doesn't resolve the case where fetching occurs around the operation. * Add more test cases for and fix issues with operation ordering * Split else onto a separate line * Update readme * Fix internal link in readme * Really fix internal link in readme * Add unit tests. * Most modules has 100% coverage. * Overall coverage is over 80%, while a few corner cases are not covered yet. * Fix a few issues caught by tests. * Cleanup. * Fix build issues. * Comment out failing unit tests. See dojo/compose/dojo#81 for details. * Add missing all.ts to fix build issue. * Switch back to previous version of compose, uncomment unit tests. * Will update accordingly based on discussion in /dojo/compose/dojo#81 * Attempt to fix build issue by adding `Rx.config.Promise` * Fix build issues on IE 10/11 caused by unavailable functionality. * Update IOS version due to issues with saucelabs environments. * Update IOS version to 9.3 due to issues with saucelabs environments. * Trigger Build. (Previous build dojo#32 seems to hang for no reason.) * Add more tests to cover more areas of logic. * Feedback changes: package name and version etc. * Move file into mixin dir. * Add createTransactionMixin. * Remove dtsGenerator grunt config * Add tests for createTransactionMixin. Fix issues caught by tests.
All dependent issues have been resolved, anything else can be handled via separate issues. |
This is an Epic issue which originally came out of the identification that the process of mutating application state and business data state was a highly "manual" process in TodoMVC and that we clearly needed a way to express the logic necessary to take business objects and have that populate application state.
At a high level, take this use case for example:
/todoitems/
.dojo-store
.TodoItemWidget
and have those states be children of aTodoItemList
dojo-app
instance can ensure that the application properly represents the underling business sate.The text was updated successfully, but these errors were encountered: