@adobe/data 0.9.7 → 0.9.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data.d.ts +1 -1
- package/ecs/database/combine-plugins.d.ts +14 -7
- package/ecs/database/combine-plugins.js +6 -3
- package/ecs/database/combine-plugins.js.map +1 -1
- package/ecs/database/create-plugin.d.ts +37 -17
- package/ecs/database/create-plugin.js +3 -30
- package/ecs/database/create-plugin.js.map +1 -1
- package/ecs/database/create-plugin.test.js +55 -0
- package/ecs/database/create-plugin.test.js.map +1 -1
- package/ecs/database/create-plugin.type-test.js +157 -0
- package/ecs/database/create-plugin.type-test.js.map +1 -1
- package/ecs/database/database-schema/create-database-schema.js +3 -3
- package/ecs/database/database-schema/create-database-schema.js.map +1 -1
- package/ecs/database/database.d.ts +43 -5
- package/ecs/database/database.js.map +1 -1
- package/ecs/database/observe-dependent-value.test.js +39 -31
- package/ecs/database/observe-dependent-value.test.js.map +1 -1
- package/ecs/database/observe-select-entities.performance.test.js +30 -31
- package/ecs/database/observe-select-entities.performance.test.js.map +1 -1
- package/ecs/database/observe-select-entities.test.js +30 -31
- package/ecs/database/observe-select-entities.test.js.map +1 -1
- package/ecs/database/observed/create-observed-database.js +7 -0
- package/ecs/database/observed/create-observed-database.js.map +1 -1
- package/ecs/database/public/create-database.d.ts +5 -34
- package/ecs/database/public/create-database.js +68 -131
- package/ecs/database/public/create-database.js.map +1 -1
- package/ecs/database/public/create-database.test.js +324 -62
- package/ecs/database/public/create-database.test.js.map +1 -1
- package/ecs/database/transactional-store/create-transactional-store.js +16 -1
- package/ecs/database/transactional-store/create-transactional-store.js.map +1 -1
- package/ecs/plugins/scheduler/scheduler.d.ts +2 -2
- package/ecs/plugins/scheduler/scheduler.js +2 -2
- package/ecs/plugins/scheduler/scheduler.js.map +1 -1
- package/ecs/undo-redo-service/create-undo-redo-service.test.js +22 -23
- package/ecs/undo-redo-service/create-undo-redo-service.test.js.map +1 -1
- package/package.json +6 -24
- package/service/async-data-service/create-lazy.d.ts +40 -0
- package/service/async-data-service/create-lazy.js +194 -0
- package/service/async-data-service/create-lazy.js.map +1 -0
- package/service/async-data-service/create-lazy.test.js +477 -0
- package/service/async-data-service/create-lazy.test.js.map +1 -0
- package/service/async-data-service/example.d.ts +60 -0
- package/service/async-data-service/example.js +35 -0
- package/service/async-data-service/example.js.map +1 -0
- package/service/async-data-service/index.d.ts +1 -0
- package/service/async-data-service/index.js +3 -0
- package/service/async-data-service/index.js.map +1 -0
- package/service/{is-data-service.d.ts → async-data-service/is-valid.d.ts} +4 -4
- package/{lit/hooks/component/component.js → service/async-data-service/is-valid.js} +1 -1
- package/service/async-data-service/is-valid.js.map +1 -0
- package/service/async-data-service/public.d.ts +2 -0
- package/service/async-data-service/public.js +4 -0
- package/service/async-data-service/public.js.map +1 -0
- package/service/index.d.ts +1 -1
- package/service/index.js +1 -0
- package/service/index.js.map +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/ecs/database/combine-plugins-test.d.ts +0 -39
- package/ecs/database/combine-plugins-test.js +0 -3
- package/ecs/database/combine-plugins-test.js.map +0 -1
- package/ecs/database/create-plugin-cryos-pattern.test.d.ts +0 -3
- package/ecs/database/create-plugin-cryos-pattern.test.js +0 -83
- package/ecs/database/create-plugin-cryos-pattern.test.js.map +0 -1
- package/ecs/database/create-plugin-graphics.test.d.ts +0 -93
- package/ecs/database/create-plugin-graphics.test.js +0 -135
- package/ecs/database/create-plugin-graphics.test.js.map +0 -1
- package/ecs/database/create-plugin-type.type-test.js +0 -563
- package/ecs/database/create-plugin-type.type-test.js.map +0 -1
- package/ecs/database/create-plugin-type.type.test.d.ts +0 -1
- package/ecs/database/create-plugin-type.type.test.js +0 -563
- package/ecs/database/create-plugin-type.type.test.js.map +0 -1
- package/ecs/database/experimental-action-types.d.ts +0 -1
- package/ecs/database/experimental-action-types.js +0 -275
- package/ecs/database/experimental-action-types.js.map +0 -1
- package/ecs/database/from-plugin.type-test.d.ts +0 -1
- package/ecs/database/from-plugin.type-test.js +0 -180
- package/ecs/database/from-plugin.type-test.js.map +0 -1
- package/ecs/database/plugin-types.d.ts +0 -1
- package/ecs/database/plugin-types.js +0 -5
- package/ecs/database/plugin-types.js.map +0 -1
- package/ecs/database/type-investigation.test.d.ts +0 -1
- package/ecs/database/type-investigation.test.js +0 -54
- package/ecs/database/type-investigation.test.js.map +0 -1
- package/lit/decorators/apply-decorator.d.ts +0 -1
- package/lit/decorators/apply-decorator.js +0 -19
- package/lit/decorators/apply-decorator.js.map +0 -1
- package/lit/decorators/apply-service-decorators.d.ts +0 -1
- package/lit/decorators/apply-service-decorators.js +0 -13
- package/lit/decorators/apply-service-decorators.js.map +0 -1
- package/lit/decorators/index.d.ts +0 -3
- package/lit/decorators/index.js +0 -5
- package/lit/decorators/index.js.map +0 -1
- package/lit/decorators/require-service.d.ts +0 -1
- package/lit/decorators/require-service.js +0 -14
- package/lit/decorators/require-service.js.map +0 -1
- package/lit/elements/application-element.d.ts +0 -9
- package/lit/elements/application-element.js +0 -42
- package/lit/elements/application-element.js.map +0 -1
- package/lit/elements/application-host.d.ts +0 -16
- package/lit/elements/application-host.js +0 -39
- package/lit/elements/application-host.js.map +0 -1
- package/lit/elements/database-element.d.ts +0 -10
- package/lit/elements/database-element.js +0 -40
- package/lit/elements/database-element.js.map +0 -1
- package/lit/elements/index.d.ts +0 -3
- package/lit/elements/index.js +0 -5
- package/lit/elements/index.js.map +0 -1
- package/lit/functions/index.d.ts +0 -1
- package/lit/functions/index.js +0 -3
- package/lit/functions/index.js.map +0 -1
- package/lit/functions/iterate-self-and-ancestors.d.ts +0 -1
- package/lit/functions/iterate-self-and-ancestors.js +0 -24
- package/lit/functions/iterate-self-and-ancestors.js.map +0 -1
- package/lit/hooks/attach-decorator.d.ts +0 -4
- package/lit/hooks/attach-decorator.js +0 -26
- package/lit/hooks/attach-decorator.js.map +0 -1
- package/lit/hooks/component/component.d.ts +0 -10
- package/lit/hooks/component/component.js.map +0 -1
- package/lit/hooks/component/stack.d.ts +0 -6
- package/lit/hooks/component/stack.js +0 -16
- package/lit/hooks/component/stack.js.map +0 -1
- package/lit/hooks/index.d.ts +0 -19
- package/lit/hooks/index.js +0 -21
- package/lit/hooks/index.js.map +0 -1
- package/lit/hooks/use-connected.d.ts +0 -2
- package/lit/hooks/use-connected.js +0 -32
- package/lit/hooks/use-connected.js.map +0 -1
- package/lit/hooks/use-debounce.d.ts +0 -8
- package/lit/hooks/use-debounce.js +0 -21
- package/lit/hooks/use-debounce.js.map +0 -1
- package/lit/hooks/use-drag-observe.d.ts +0 -25
- package/lit/hooks/use-drag-observe.js +0 -35
- package/lit/hooks/use-drag-observe.js.map +0 -1
- package/lit/hooks/use-drag-transaction.d.ts +0 -7
- package/lit/hooks/use-drag-transaction.js +0 -35
- package/lit/hooks/use-drag-transaction.js.map +0 -1
- package/lit/hooks/use-draggable.d.ts +0 -15
- package/lit/hooks/use-draggable.js +0 -96
- package/lit/hooks/use-draggable.js.map +0 -1
- package/lit/hooks/use-effect.d.ts +0 -3
- package/lit/hooks/use-effect.js +0 -14
- package/lit/hooks/use-effect.js.map +0 -1
- package/lit/hooks/use-element.d.ts +0 -7
- package/lit/hooks/use-element.js +0 -67
- package/lit/hooks/use-element.js.map +0 -1
- package/lit/hooks/use-memo.d.ts +0 -1
- package/lit/hooks/use-memo.js +0 -13
- package/lit/hooks/use-memo.js.map +0 -1
- package/lit/hooks/use-observable-values.d.ts +0 -4
- package/lit/hooks/use-observable-values.js +0 -9
- package/lit/hooks/use-observable-values.js.map +0 -1
- package/lit/hooks/use-observable.d.ts +0 -2
- package/lit/hooks/use-observable.js +0 -13
- package/lit/hooks/use-observable.js.map +0 -1
- package/lit/hooks/use-ref.d.ts +0 -3
- package/lit/hooks/use-ref.js +0 -7
- package/lit/hooks/use-ref.js.map +0 -1
- package/lit/hooks/use-resize-observer.d.ts +0 -12
- package/lit/hooks/use-resize-observer.js +0 -23
- package/lit/hooks/use-resize-observer.js.map +0 -1
- package/lit/hooks/use-state.d.ts +0 -2
- package/lit/hooks/use-state.js +0 -15
- package/lit/hooks/use-state.js.map +0 -1
- package/lit/hooks/use-updated.d.ts +0 -4
- package/lit/hooks/use-updated.js +0 -40
- package/lit/hooks/use-updated.js.map +0 -1
- package/lit/hooks/use-window-event.d.ts +0 -1
- package/lit/hooks/use-window-event.js +0 -11
- package/lit/hooks/use-window-event.js.map +0 -1
- package/lit/hooks/with-hooks.d.ts +0 -2
- package/lit/hooks/with-hooks.js +0 -16
- package/lit/hooks/with-hooks.js.map +0 -1
- package/lit/index.d.ts +0 -4
- package/lit/index.js +0 -5
- package/lit/index.js.map +0 -1
- package/normalize.test.d.ts +0 -1
- package/normalize.test.js +0 -28
- package/normalize.test.js.map +0 -1
- package/samples/index.d.ts +0 -13
- package/samples/index.js +0 -7
- package/samples/index.js.map +0 -1
- package/samples/todo/elements/todo-list/todo-list-presentation.d.ts +0 -8
- package/samples/todo/elements/todo-list/todo-list-presentation.js +0 -12
- package/samples/todo/elements/todo-list/todo-list-presentation.js.map +0 -1
- package/samples/todo/elements/todo-list/todo-list.css.d.ts +0 -1
- package/samples/todo/elements/todo-list/todo-list.css.js +0 -11
- package/samples/todo/elements/todo-list/todo-list.css.js.map +0 -1
- package/samples/todo/elements/todo-list/todo-list.d.ts +0 -12
- package/samples/todo/elements/todo-list/todo-list.js +0 -44
- package/samples/todo/elements/todo-list/todo-list.js.map +0 -1
- package/samples/todo/elements/todo-row/index.d.ts +0 -1
- package/samples/todo/elements/todo-row/index.js +0 -3
- package/samples/todo/elements/todo-row/index.js.map +0 -1
- package/samples/todo/elements/todo-row/todo-row-presentation.d.ts +0 -18
- package/samples/todo/elements/todo-row/todo-row-presentation.js +0 -50
- package/samples/todo/elements/todo-row/todo-row-presentation.js.map +0 -1
- package/samples/todo/elements/todo-row/todo-row.css.d.ts +0 -1
- package/samples/todo/elements/todo-row/todo-row.css.js +0 -49
- package/samples/todo/elements/todo-row/todo-row.css.js.map +0 -1
- package/samples/todo/elements/todo-row/todo-row.d.ts +0 -14
- package/samples/todo/elements/todo-row/todo-row.js +0 -44
- package/samples/todo/elements/todo-row/todo-row.js.map +0 -1
- package/samples/todo/elements/todo-toolbar/index.d.ts +0 -1
- package/samples/todo/elements/todo-toolbar/index.js +0 -3
- package/samples/todo/elements/todo-toolbar/index.js.map +0 -1
- package/samples/todo/elements/todo-toolbar/todo-toolbar-presentation.d.ts +0 -22
- package/samples/todo/elements/todo-toolbar/todo-toolbar-presentation.js +0 -41
- package/samples/todo/elements/todo-toolbar/todo-toolbar-presentation.js.map +0 -1
- package/samples/todo/elements/todo-toolbar/todo-toolbar.css.d.ts +0 -1
- package/samples/todo/elements/todo-toolbar/todo-toolbar.css.js +0 -34
- package/samples/todo/elements/todo-toolbar/todo-toolbar.css.js.map +0 -1
- package/samples/todo/elements/todo-toolbar/todo-toolbar.d.ts +0 -11
- package/samples/todo/elements/todo-toolbar/todo-toolbar.js +0 -61
- package/samples/todo/elements/todo-toolbar/todo-toolbar.js.map +0 -1
- package/samples/todo/elements/todo-undo-redo/index.d.ts +0 -1
- package/samples/todo/elements/todo-undo-redo/index.js +0 -3
- package/samples/todo/elements/todo-undo-redo/index.js.map +0 -1
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo-presentation.d.ts +0 -17
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo-presentation.js +0 -29
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo-presentation.js.map +0 -1
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo.css.d.ts +0 -1
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo.css.js +0 -12
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo.css.js.map +0 -1
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo.d.ts +0 -11
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo.js +0 -36
- package/samples/todo/elements/todo-undo-redo/todo-undo-redo.js.map +0 -1
- package/samples/todo/services/dependent-state-service/create-dependent-state-service.d.ts +0 -6
- package/samples/todo/services/dependent-state-service/create-dependent-state-service.js +0 -5
- package/samples/todo/services/dependent-state-service/create-dependent-state-service.js.map +0 -1
- package/samples/todo/services/dependent-state-service/dependent-state/all-todos.d.ts +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state/all-todos.js +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state/all-todos.js.map +0 -1
- package/samples/todo/services/dependent-state-service/dependent-state/complete-todos.d.ts +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state/complete-todos.js +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state/complete-todos.js.map +0 -1
- package/samples/todo/services/dependent-state-service/dependent-state/incomplete-todos.d.ts +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state/incomplete-todos.js +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state/incomplete-todos.js.map +0 -1
- package/samples/todo/services/dependent-state-service/dependent-state/index.d.ts +0 -3
- package/samples/todo/services/dependent-state-service/dependent-state/index.js +0 -5
- package/samples/todo/services/dependent-state-service/dependent-state/index.js.map +0 -1
- package/samples/todo/services/dependent-state-service/dependent-state-service.d.ts +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state-service.js +0 -2
- package/samples/todo/services/dependent-state-service/dependent-state-service.js.map +0 -1
- package/samples/todo/services/main-service/create-main-service.d.ts +0 -8
- package/samples/todo/services/main-service/create-main-service.js +0 -39
- package/samples/todo/services/main-service/create-main-service.js.map +0 -1
- package/samples/todo/services/main-service/todo-main-service.d.ts +0 -18
- package/samples/todo/services/main-service/todo-main-service.js +0 -2
- package/samples/todo/services/main-service/todo-main-service.js.map +0 -1
- package/samples/todo/services/state-service/create-todo-database.d.ts +0 -37
- package/samples/todo/services/state-service/create-todo-database.js +0 -10
- package/samples/todo/services/state-service/create-todo-database.js.map +0 -1
- package/samples/todo/services/state-service/create-todo-store.d.ts +0 -37
- package/samples/todo/services/state-service/create-todo-store.js +0 -24
- package/samples/todo/services/state-service/create-todo-store.js.map +0 -1
- package/samples/todo/services/state-service/todo-state-service.d.ts +0 -5
- package/samples/todo/services/state-service/todo-state-service.js +0 -2
- package/samples/todo/services/state-service/todo-state-service.js.map +0 -1
- package/samples/todo/services/state-service/transactions/create-bulk-todos.d.ts +0 -2
- package/samples/todo/services/state-service/transactions/create-bulk-todos.js +0 -10
- package/samples/todo/services/state-service/transactions/create-bulk-todos.js.map +0 -1
- package/samples/todo/services/state-service/transactions/create-todo.d.ts +0 -5
- package/samples/todo/services/state-service/transactions/create-todo.js +0 -13
- package/samples/todo/services/state-service/transactions/create-todo.js.map +0 -1
- package/samples/todo/services/state-service/transactions/create-todo.test.d.ts +0 -1
- package/samples/todo/services/state-service/transactions/create-todo.test.js +0 -16
- package/samples/todo/services/state-service/transactions/create-todo.test.js.map +0 -1
- package/samples/todo/services/state-service/transactions/delete-all-todos.d.ts +0 -2
- package/samples/todo/services/state-service/transactions/delete-all-todos.js +0 -16
- package/samples/todo/services/state-service/transactions/delete-all-todos.js.map +0 -1
- package/samples/todo/services/state-service/transactions/delete-todo.d.ts +0 -3
- package/samples/todo/services/state-service/transactions/delete-todo.js +0 -8
- package/samples/todo/services/state-service/transactions/delete-todo.js.map +0 -1
- package/samples/todo/services/state-service/transactions/delete-todo.test.d.ts +0 -1
- package/samples/todo/services/state-service/transactions/delete-todo.test.js +0 -24
- package/samples/todo/services/state-service/transactions/delete-todo.test.js.map +0 -1
- package/samples/todo/services/state-service/transactions/drag-todo.d.ts +0 -7
- package/samples/todo/services/state-service/transactions/drag-todo.js +0 -17
- package/samples/todo/services/state-service/transactions/drag-todo.js.map +0 -1
- package/samples/todo/services/state-service/transactions/index.d.ts +0 -6
- package/samples/todo/services/state-service/transactions/index.js +0 -9
- package/samples/todo/services/state-service/transactions/index.js.map +0 -1
- package/samples/todo/services/state-service/transactions/reorder-todos.d.ts +0 -6
- package/samples/todo/services/state-service/transactions/reorder-todos.js +0 -11
- package/samples/todo/services/state-service/transactions/reorder-todos.js.map +0 -1
- package/samples/todo/services/state-service/transactions/toggle-complete.d.ts +0 -3
- package/samples/todo/services/state-service/transactions/toggle-complete.js +0 -11
- package/samples/todo/services/state-service/transactions/toggle-complete.js.map +0 -1
- package/samples/todo/services/state-service/transactions/toggle-complete.test.d.ts +0 -1
- package/samples/todo/services/state-service/transactions/toggle-complete.test.js +0 -65
- package/samples/todo/services/state-service/transactions/toggle-complete.test.js.map +0 -1
- package/samples/todo/todo-element.d.ts +0 -4
- package/samples/todo/todo-element.js +0 -4
- package/samples/todo/todo-element.js.map +0 -1
- package/samples/todo/todo-host.d.ts +0 -8
- package/samples/todo/todo-host.js +0 -35
- package/samples/todo/todo-host.js.map +0 -1
- package/samples/todo/todo-main-element.d.ts +0 -10
- package/samples/todo/todo-main-element.js +0 -47
- package/samples/todo/todo-main-element.js.map +0 -1
- package/samples/todo/todo-sample.d.ts +0 -3
- package/samples/todo/todo-sample.js +0 -19
- package/samples/todo/todo-sample.js.map +0 -1
- package/service/is-data-service.js +0 -2
- package/service/is-data-service.js.map +0 -1
- package/typed-buffer/public.d.ts +0 -2
- package/typed-buffer/public.js +0 -4
- package/typed-buffer/public.js.map +0 -1
- /package/{ecs/database/create-plugin-type.type-test.d.ts → service/async-data-service/create-lazy.test.d.ts} +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// MAIN FUNCTION SIGNATURE
|
|
4
|
+
// ============================================================================
|
|
5
|
+
/**
|
|
6
|
+
* Creates a lazy-loading wrapper factory for an AsyncDataService.
|
|
7
|
+
* The real service is only loaded when the first property is accessed.
|
|
8
|
+
* All calls are queued and executed in order once the service loads.
|
|
9
|
+
*
|
|
10
|
+
* @param load - Function that loads and returns the real service (may accept args)
|
|
11
|
+
* @param properties - Object describing how to wrap each service property
|
|
12
|
+
* @returns A factory function that creates lazy service instances
|
|
13
|
+
*
|
|
14
|
+
* TypeScript will enforce:
|
|
15
|
+
* - All service properties must be declared in properties object
|
|
16
|
+
* - Each descriptor must match the actual property type
|
|
17
|
+
* - Clear errors indicate what is missing or wrong
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // Service with no args
|
|
22
|
+
* const createLazySimple = createLazy(
|
|
23
|
+
* () => import('./simple').then(m => m.create()),
|
|
24
|
+
* { data: 'observe', fetch: 'fn:promise' }
|
|
25
|
+
* );
|
|
26
|
+
* const service = createLazySimple();
|
|
27
|
+
*
|
|
28
|
+
* // Service with args
|
|
29
|
+
* const createLazyConfig = createLazy(
|
|
30
|
+
* (config: Config) => import('./service').then(m => m.create(config)),
|
|
31
|
+
* { data: 'observe', fetch: 'fn:promise' }
|
|
32
|
+
* );
|
|
33
|
+
* const service = createLazyConfig({ apiUrl: '...' });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function createLazy(load, properties) {
|
|
37
|
+
// Return factory function that creates lazy service instances
|
|
38
|
+
return ((...factoryArgs) => {
|
|
39
|
+
// Shared loading state for this instance
|
|
40
|
+
let loadPromise = null;
|
|
41
|
+
let loadedService = null;
|
|
42
|
+
const ensureLoading = () => {
|
|
43
|
+
if (loadedService) {
|
|
44
|
+
return Promise.resolve(loadedService);
|
|
45
|
+
}
|
|
46
|
+
if (loadPromise) {
|
|
47
|
+
return loadPromise;
|
|
48
|
+
}
|
|
49
|
+
loadPromise = load(...factoryArgs).then((service) => {
|
|
50
|
+
loadedService = service;
|
|
51
|
+
return service;
|
|
52
|
+
});
|
|
53
|
+
return loadPromise;
|
|
54
|
+
};
|
|
55
|
+
// Build lazy service object
|
|
56
|
+
const lazyService = {
|
|
57
|
+
serviceName: 'lazy-service',
|
|
58
|
+
};
|
|
59
|
+
// Wrap each property based on its descriptor
|
|
60
|
+
for (const [key, descriptor] of Object.entries(properties)) {
|
|
61
|
+
if (descriptor === 'observe') {
|
|
62
|
+
// Observe property - defer subscription until service loads
|
|
63
|
+
lazyService[key] = (notify) => {
|
|
64
|
+
let unobserveReal = null;
|
|
65
|
+
let isCancelled = false;
|
|
66
|
+
ensureLoading().then((service) => {
|
|
67
|
+
if (!isCancelled && service.serviceName !== 'lazy-service') {
|
|
68
|
+
// Update lazy service name once real service loads
|
|
69
|
+
lazyService.serviceName = `lazy-${service.serviceName}`;
|
|
70
|
+
}
|
|
71
|
+
if (!isCancelled) {
|
|
72
|
+
unobserveReal = service[key](notify);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return () => {
|
|
76
|
+
isCancelled = true;
|
|
77
|
+
unobserveReal?.();
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
else if (descriptor === 'fn:promise') {
|
|
82
|
+
const queue = [];
|
|
83
|
+
let isProcessing = false;
|
|
84
|
+
lazyService[key] = (...args) => {
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
queue.push({ args, resolve, reject });
|
|
87
|
+
if (!isProcessing) {
|
|
88
|
+
isProcessing = true;
|
|
89
|
+
ensureLoading().then(async (service) => {
|
|
90
|
+
if (service.serviceName !== 'lazy-service') {
|
|
91
|
+
lazyService.serviceName = `lazy-${service.serviceName}`;
|
|
92
|
+
}
|
|
93
|
+
// Execute all queued calls in order
|
|
94
|
+
while (queue.length > 0) {
|
|
95
|
+
const call = queue.shift();
|
|
96
|
+
try {
|
|
97
|
+
const result = await service[key](...call.args);
|
|
98
|
+
call.resolve(result);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
call.reject(error);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}).catch(error => {
|
|
105
|
+
// Service load failed, reject all queued calls
|
|
106
|
+
while (queue.length > 0) {
|
|
107
|
+
queue.shift().reject(error);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
else if (descriptor === 'fn:void') {
|
|
115
|
+
// Void function - queue calls and execute after load
|
|
116
|
+
const queue = [];
|
|
117
|
+
let isProcessing = false;
|
|
118
|
+
lazyService[key] = (...args) => {
|
|
119
|
+
queue.push(args);
|
|
120
|
+
if (!isProcessing) {
|
|
121
|
+
isProcessing = true;
|
|
122
|
+
ensureLoading().then((service) => {
|
|
123
|
+
if (service.serviceName !== 'lazy-service') {
|
|
124
|
+
lazyService.serviceName = `lazy-${service.serviceName}`;
|
|
125
|
+
}
|
|
126
|
+
// Execute all queued calls in order
|
|
127
|
+
while (queue.length > 0) {
|
|
128
|
+
const args = queue.shift();
|
|
129
|
+
service[key](...args);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
else if (descriptor === 'fn:observe') {
|
|
136
|
+
// Observe function - returns Observe that waits for service
|
|
137
|
+
lazyService[key] = (...args) => {
|
|
138
|
+
return (notify) => {
|
|
139
|
+
let unobserveReal = null;
|
|
140
|
+
let isCancelled = false;
|
|
141
|
+
ensureLoading().then((service) => {
|
|
142
|
+
if (service.serviceName !== 'lazy-service') {
|
|
143
|
+
lazyService.serviceName = `lazy-${service.serviceName}`;
|
|
144
|
+
}
|
|
145
|
+
if (!isCancelled) {
|
|
146
|
+
const realObserve = service[key](...args);
|
|
147
|
+
unobserveReal = realObserve(notify);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
return () => {
|
|
151
|
+
isCancelled = true;
|
|
152
|
+
unobserveReal?.();
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
else if (descriptor === 'fn:generator') {
|
|
158
|
+
// AsyncGenerator function - returns generator that waits for service
|
|
159
|
+
lazyService[key] = (...args) => {
|
|
160
|
+
let realGenerator = null;
|
|
161
|
+
return {
|
|
162
|
+
async next() {
|
|
163
|
+
if (!realGenerator) {
|
|
164
|
+
const service = await ensureLoading();
|
|
165
|
+
if (service.serviceName !== 'lazy-service') {
|
|
166
|
+
lazyService.serviceName = `lazy-${service.serviceName}`;
|
|
167
|
+
}
|
|
168
|
+
realGenerator = service[key](...args);
|
|
169
|
+
}
|
|
170
|
+
return realGenerator.next();
|
|
171
|
+
},
|
|
172
|
+
async return(value) {
|
|
173
|
+
if (realGenerator) {
|
|
174
|
+
return realGenerator.return(value);
|
|
175
|
+
}
|
|
176
|
+
return { done: true, value: value };
|
|
177
|
+
},
|
|
178
|
+
async throw(e) {
|
|
179
|
+
if (realGenerator) {
|
|
180
|
+
return realGenerator.throw(e);
|
|
181
|
+
}
|
|
182
|
+
throw e;
|
|
183
|
+
},
|
|
184
|
+
[Symbol.asyncIterator]() {
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return lazyService;
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=create-lazy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-lazy.js","sourceRoot":"","sources":["../../../src/service/async-data-service/create-lazy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
// © 2026 Adobe. MIT License. See /LICENSE for details.
|
|
2
|
+
import { describe, test } from 'vitest';
|
|
3
|
+
import { assert } from 'riteway/vitest';
|
|
4
|
+
import { createLazy } from "./create-lazy.js";
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// VALID USAGE TESTS
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// ✅ Test 1: Complete descriptor for SimpleAuthService
|
|
9
|
+
const validAuth = createLazy(() => Promise.resolve({}), {
|
|
10
|
+
isSignedIn: 'observe',
|
|
11
|
+
accessToken: 'observe',
|
|
12
|
+
userProfile: 'observe',
|
|
13
|
+
showSignInDialog: 'fn:void',
|
|
14
|
+
hideSignInDialog: 'fn:void',
|
|
15
|
+
refreshToken: 'fn:promise',
|
|
16
|
+
signIn: 'fn:promise',
|
|
17
|
+
signOut: 'fn:promise'
|
|
18
|
+
});
|
|
19
|
+
// ✅ Test 2: Service with function returning Observe
|
|
20
|
+
const validObserveFn = createLazy(() => Promise.resolve({}), {
|
|
21
|
+
allUsers: 'observe',
|
|
22
|
+
selectUser: 'fn:observe',
|
|
23
|
+
fetchData: 'fn:promise'
|
|
24
|
+
});
|
|
25
|
+
// ✅ Test 3: Service with AsyncGenerator
|
|
26
|
+
const validGenerator = createLazy(() => Promise.resolve({}), {
|
|
27
|
+
status: 'observe',
|
|
28
|
+
streamEvents: 'fn:generator',
|
|
29
|
+
cancel: 'fn:void'
|
|
30
|
+
});
|
|
31
|
+
const validWithArgs = createLazy((args) => {
|
|
32
|
+
// args is properly typed as ServiceConfig
|
|
33
|
+
console.log(args.apiUrl);
|
|
34
|
+
return Promise.resolve({});
|
|
35
|
+
}, {
|
|
36
|
+
config: 'observe',
|
|
37
|
+
fetch: 'fn:promise'
|
|
38
|
+
});
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// ERROR TESTS (These should produce TypeScript errors)
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// ❌ Test 5: Missing property 'refreshToken'
|
|
43
|
+
const errorMissing = createLazy(() => Promise.resolve({}),
|
|
44
|
+
// @ts-expect-error - Missing property 'refreshToken' in descriptor
|
|
45
|
+
{
|
|
46
|
+
isSignedIn: 'observe',
|
|
47
|
+
accessToken: 'observe',
|
|
48
|
+
userProfile: 'observe',
|
|
49
|
+
showSignInDialog: 'fn:void',
|
|
50
|
+
hideSignInDialog: 'fn:void',
|
|
51
|
+
// Missing: refreshToken
|
|
52
|
+
signIn: 'fn:promise',
|
|
53
|
+
signOut: 'fn:promise'
|
|
54
|
+
});
|
|
55
|
+
// ❌ Test 6: Wrong descriptor type (observe property marked as fn:observe)
|
|
56
|
+
const errorWrongType1 = createLazy(() => Promise.resolve({}), {
|
|
57
|
+
// @ts-expect-error - Wrong descriptor type
|
|
58
|
+
isSignedIn: 'fn:observe', // WRONG: should be 'observe'
|
|
59
|
+
accessToken: 'observe',
|
|
60
|
+
userProfile: 'observe',
|
|
61
|
+
showSignInDialog: 'fn:void',
|
|
62
|
+
hideSignInDialog: 'fn:void',
|
|
63
|
+
refreshToken: 'fn:promise',
|
|
64
|
+
signIn: 'fn:promise',
|
|
65
|
+
signOut: 'fn:promise'
|
|
66
|
+
});
|
|
67
|
+
// ❌ Test 7: Wrong descriptor type (void function marked as fn:promise)
|
|
68
|
+
const errorWrongType2 = createLazy(() => Promise.resolve({}), {
|
|
69
|
+
isSignedIn: 'observe',
|
|
70
|
+
accessToken: 'observe',
|
|
71
|
+
userProfile: 'observe',
|
|
72
|
+
// @ts-expect-error - Wrong descriptor type
|
|
73
|
+
showSignInDialog: 'fn:promise', // WRONG: should be 'fn:void'
|
|
74
|
+
hideSignInDialog: 'fn:void',
|
|
75
|
+
refreshToken: 'fn:promise',
|
|
76
|
+
signIn: 'fn:promise',
|
|
77
|
+
signOut: 'fn:promise'
|
|
78
|
+
});
|
|
79
|
+
// ❌ Test 8: Extra property that doesn't exist in service
|
|
80
|
+
const errorExtra = createLazy(() => Promise.resolve({}), {
|
|
81
|
+
allUsers: 'observe',
|
|
82
|
+
selectUser: 'fn:observe',
|
|
83
|
+
fetchData: 'fn:promise',
|
|
84
|
+
// @ts-expect-error - Extra property
|
|
85
|
+
unknownProperty: 'observe' // EXTRA: doesn't exist in service
|
|
86
|
+
});
|
|
87
|
+
// ❌ Test 9: Wrong descriptor for fn:observe (marked as observe)
|
|
88
|
+
const errorObserveFn = createLazy(() => Promise.resolve({}), {
|
|
89
|
+
allUsers: 'observe',
|
|
90
|
+
// @ts-expect-error - Wrong descriptor type
|
|
91
|
+
selectUser: 'observe', // WRONG: should be 'fn:observe'
|
|
92
|
+
fetchData: 'fn:promise'
|
|
93
|
+
});
|
|
94
|
+
// ❌ Test 10: Wrong descriptor for generator
|
|
95
|
+
const errorGenerator = createLazy(() => Promise.resolve({}), {
|
|
96
|
+
status: 'observe',
|
|
97
|
+
// @ts-expect-error - Wrong descriptor type
|
|
98
|
+
streamEvents: 'fn:promise', // WRONG: should be 'fn:generator'
|
|
99
|
+
cancel: 'fn:void'
|
|
100
|
+
});
|
|
101
|
+
// ============================================================================
|
|
102
|
+
// RUNTIME TESTS
|
|
103
|
+
// ============================================================================
|
|
104
|
+
describe('createLazy', () => {
|
|
105
|
+
test('factory pattern', async () => {
|
|
106
|
+
const createTestService = () => {
|
|
107
|
+
return Promise.resolve({
|
|
108
|
+
serviceName: 'test-service',
|
|
109
|
+
value: (notify) => {
|
|
110
|
+
notify('test-value');
|
|
111
|
+
return () => { };
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
const factory = createLazy(createTestService, { value: 'observe' });
|
|
116
|
+
assert({
|
|
117
|
+
given: 'createLazy is called',
|
|
118
|
+
should: 'return a factory function',
|
|
119
|
+
actual: typeof factory,
|
|
120
|
+
expected: 'function'
|
|
121
|
+
});
|
|
122
|
+
const service = factory();
|
|
123
|
+
assert({
|
|
124
|
+
given: 'factory function is called',
|
|
125
|
+
should: 'return a service with serviceName',
|
|
126
|
+
actual: typeof service.serviceName,
|
|
127
|
+
expected: 'string'
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
test('observe property', async () => {
|
|
131
|
+
const createTestService = () => {
|
|
132
|
+
return Promise.resolve({
|
|
133
|
+
serviceName: 'test-service',
|
|
134
|
+
value: (notify) => {
|
|
135
|
+
notify('test-value');
|
|
136
|
+
return () => { };
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
const factory = createLazy(createTestService, { value: 'observe' });
|
|
141
|
+
const service = factory();
|
|
142
|
+
let receivedValue = null;
|
|
143
|
+
const unobserve = service.value((value) => {
|
|
144
|
+
receivedValue = value;
|
|
145
|
+
});
|
|
146
|
+
// Wait for async load
|
|
147
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
148
|
+
assert({
|
|
149
|
+
given: 'observe property is subscribed',
|
|
150
|
+
should: 'receive value from real service after load',
|
|
151
|
+
actual: receivedValue,
|
|
152
|
+
expected: 'test-value'
|
|
153
|
+
});
|
|
154
|
+
unobserve();
|
|
155
|
+
});
|
|
156
|
+
test('observe property returns same instance', async () => {
|
|
157
|
+
const createTestService = () => {
|
|
158
|
+
return Promise.resolve({
|
|
159
|
+
serviceName: 'test-service',
|
|
160
|
+
value: (notify) => {
|
|
161
|
+
notify('test-value');
|
|
162
|
+
return () => { };
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
const factory = createLazy(createTestService, { value: 'observe' });
|
|
167
|
+
const service = factory();
|
|
168
|
+
const observe1 = service.value;
|
|
169
|
+
const observe2 = service.value;
|
|
170
|
+
assert({
|
|
171
|
+
given: 'observe property is accessed multiple times',
|
|
172
|
+
should: 'return the same Observe instance',
|
|
173
|
+
actual: observe1 === observe2,
|
|
174
|
+
expected: true
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
test('promise function', async () => {
|
|
178
|
+
const createTestService = () => {
|
|
179
|
+
return Promise.resolve({
|
|
180
|
+
serviceName: 'test-service',
|
|
181
|
+
fetchData: async (id) => {
|
|
182
|
+
return { value: `data-${id}` };
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
const factory = createLazy(createTestService, { fetchData: 'fn:promise' });
|
|
187
|
+
const service = factory();
|
|
188
|
+
const result = await service.fetchData('123');
|
|
189
|
+
assert({
|
|
190
|
+
given: 'promise function is called',
|
|
191
|
+
should: 'return result from real service',
|
|
192
|
+
actual: result.value,
|
|
193
|
+
expected: 'data-123'
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
test('promise function queuing', async () => {
|
|
197
|
+
const calls = [];
|
|
198
|
+
const createTestService = () => {
|
|
199
|
+
return new Promise(resolve => {
|
|
200
|
+
setTimeout(() => {
|
|
201
|
+
resolve({
|
|
202
|
+
serviceName: 'test-service',
|
|
203
|
+
fetchData: async (id) => {
|
|
204
|
+
calls.push(id);
|
|
205
|
+
return `result-${id}`;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}, 50);
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
const factory = createLazy(createTestService, { fetchData: 'fn:promise' });
|
|
212
|
+
const service = factory();
|
|
213
|
+
// Call multiple times before service loads
|
|
214
|
+
const p1 = service.fetchData('a');
|
|
215
|
+
const p2 = service.fetchData('b');
|
|
216
|
+
const p3 = service.fetchData('c');
|
|
217
|
+
const results = await Promise.all([p1, p2, p3]);
|
|
218
|
+
assert({
|
|
219
|
+
given: 'multiple calls made before service loads',
|
|
220
|
+
should: 'execute all calls in order',
|
|
221
|
+
actual: calls.join(','),
|
|
222
|
+
expected: 'a,b,c'
|
|
223
|
+
});
|
|
224
|
+
assert({
|
|
225
|
+
given: 'queued calls complete',
|
|
226
|
+
should: 'return correct results',
|
|
227
|
+
actual: results.join(','),
|
|
228
|
+
expected: 'result-a,result-b,result-c'
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
test('promise function returns same instance', async () => {
|
|
232
|
+
const factory = createLazy(() => Promise.resolve({
|
|
233
|
+
serviceName: 'test-service',
|
|
234
|
+
fetchData: async (id) => `result-${id}`
|
|
235
|
+
}), { fetchData: 'fn:promise' });
|
|
236
|
+
const service = factory();
|
|
237
|
+
const fn1 = service.fetchData;
|
|
238
|
+
const fn2 = service.fetchData;
|
|
239
|
+
assert({
|
|
240
|
+
given: 'promise function property is accessed multiple times',
|
|
241
|
+
should: 'return the same function instance',
|
|
242
|
+
actual: fn1 === fn2,
|
|
243
|
+
expected: true
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
test('promise function calls return different promises', async () => {
|
|
247
|
+
const factory = createLazy(() => Promise.resolve({
|
|
248
|
+
serviceName: 'test-service',
|
|
249
|
+
fetchData: async (id) => `result-${id}`
|
|
250
|
+
}), { fetchData: 'fn:promise' });
|
|
251
|
+
const service = factory();
|
|
252
|
+
const promise1 = service.fetchData('id-1');
|
|
253
|
+
const promise2 = service.fetchData('id-1');
|
|
254
|
+
const promise3 = service.fetchData('id-2');
|
|
255
|
+
assert({
|
|
256
|
+
given: 'promise function is called multiple times',
|
|
257
|
+
should: 'return different Promise instances',
|
|
258
|
+
actual: promise1 !== promise2 && promise1 !== promise3,
|
|
259
|
+
expected: true
|
|
260
|
+
});
|
|
261
|
+
const results = await Promise.all([promise1, promise2, promise3]);
|
|
262
|
+
assert({
|
|
263
|
+
given: 'promise function called with different args',
|
|
264
|
+
should: 'resolve to correct values independently',
|
|
265
|
+
actual: results.join(','),
|
|
266
|
+
expected: 'result-id-1,result-id-1,result-id-2'
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
test('void function', async () => {
|
|
270
|
+
const events = [];
|
|
271
|
+
const createTestService = () => {
|
|
272
|
+
return Promise.resolve({
|
|
273
|
+
serviceName: 'test-service',
|
|
274
|
+
track: (event) => {
|
|
275
|
+
events.push(event);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
const factory = createLazy(createTestService, { track: 'fn:void' });
|
|
280
|
+
const service = factory();
|
|
281
|
+
service.track('event-1');
|
|
282
|
+
service.track('event-2');
|
|
283
|
+
// Wait for async load and execution
|
|
284
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
285
|
+
assert({
|
|
286
|
+
given: 'void functions are called',
|
|
287
|
+
should: 'execute all calls in order after load',
|
|
288
|
+
actual: events.join(','),
|
|
289
|
+
expected: 'event-1,event-2'
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
test('observe function', async () => {
|
|
293
|
+
const createTestService = () => {
|
|
294
|
+
return Promise.resolve({
|
|
295
|
+
serviceName: 'test-service',
|
|
296
|
+
selectUser: (id) => (notify) => {
|
|
297
|
+
notify(`user-${id}`);
|
|
298
|
+
return () => { };
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
};
|
|
302
|
+
const factory = createLazy(createTestService, { selectUser: 'fn:observe' });
|
|
303
|
+
const service = factory();
|
|
304
|
+
let receivedValue = null;
|
|
305
|
+
const observe = service.selectUser('123');
|
|
306
|
+
const unobserve = observe((value) => {
|
|
307
|
+
receivedValue = value;
|
|
308
|
+
});
|
|
309
|
+
// Wait for async load
|
|
310
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
311
|
+
assert({
|
|
312
|
+
given: 'observe function is called and subscribed',
|
|
313
|
+
should: 'receive value from real service',
|
|
314
|
+
actual: receivedValue,
|
|
315
|
+
expected: 'user-123'
|
|
316
|
+
});
|
|
317
|
+
unobserve();
|
|
318
|
+
});
|
|
319
|
+
test('observe function returns same instance', async () => {
|
|
320
|
+
const factory = createLazy(() => Promise.resolve({
|
|
321
|
+
serviceName: 'test-service',
|
|
322
|
+
selectUser: (id) => (notify) => {
|
|
323
|
+
notify(`user-${id}`);
|
|
324
|
+
return () => { };
|
|
325
|
+
}
|
|
326
|
+
}), { selectUser: 'fn:observe' });
|
|
327
|
+
const service = factory();
|
|
328
|
+
const fn1 = service.selectUser;
|
|
329
|
+
const fn2 = service.selectUser;
|
|
330
|
+
assert({
|
|
331
|
+
given: 'observe function property is accessed multiple times',
|
|
332
|
+
should: 'return the same function instance',
|
|
333
|
+
actual: fn1 === fn2,
|
|
334
|
+
expected: true
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
test('observe function calls return different instances', async () => {
|
|
338
|
+
const factory = createLazy(() => Promise.resolve({
|
|
339
|
+
serviceName: 'test-service',
|
|
340
|
+
selectUser: (id) => (notify) => {
|
|
341
|
+
notify(`user-${id}`);
|
|
342
|
+
return () => { };
|
|
343
|
+
}
|
|
344
|
+
}), { selectUser: 'fn:observe' });
|
|
345
|
+
const service = factory();
|
|
346
|
+
const observe1 = service.selectUser('id-1');
|
|
347
|
+
const observe2 = service.selectUser('id-1');
|
|
348
|
+
const observe3 = service.selectUser('id-2');
|
|
349
|
+
assert({
|
|
350
|
+
given: 'observe function is called multiple times with same args',
|
|
351
|
+
should: 'return different Observe instances',
|
|
352
|
+
actual: observe1 !== observe2,
|
|
353
|
+
expected: true
|
|
354
|
+
});
|
|
355
|
+
assert({
|
|
356
|
+
given: 'observe function is called with different args',
|
|
357
|
+
should: 'return different Observe instances',
|
|
358
|
+
actual: observe1 !== observe3,
|
|
359
|
+
expected: true
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
test('observe function calls with different args work independently', async () => {
|
|
363
|
+
const factory = createLazy(() => Promise.resolve({
|
|
364
|
+
serviceName: 'test-service',
|
|
365
|
+
selectUser: (id) => (notify) => {
|
|
366
|
+
notify(`user-${id}`);
|
|
367
|
+
return () => { };
|
|
368
|
+
}
|
|
369
|
+
}), { selectUser: 'fn:observe' });
|
|
370
|
+
const service = factory();
|
|
371
|
+
const values = [];
|
|
372
|
+
const observe1 = service.selectUser('id-1');
|
|
373
|
+
const unobserve1 = observe1((value) => values.push(`obs1:${value}`));
|
|
374
|
+
const observe2 = service.selectUser('id-2');
|
|
375
|
+
const unobserve2 = observe2((value) => values.push(`obs2:${value}`));
|
|
376
|
+
// Wait for async load
|
|
377
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
378
|
+
assert({
|
|
379
|
+
given: 'multiple observe function calls with different args',
|
|
380
|
+
should: 'each receive their own values independently',
|
|
381
|
+
actual: values.sort().join(','),
|
|
382
|
+
expected: 'obs1:user-id-1,obs2:user-id-2'
|
|
383
|
+
});
|
|
384
|
+
unobserve1();
|
|
385
|
+
unobserve2();
|
|
386
|
+
});
|
|
387
|
+
test('generator function', async () => {
|
|
388
|
+
const createTestService = () => {
|
|
389
|
+
return Promise.resolve({
|
|
390
|
+
serviceName: 'test-service',
|
|
391
|
+
streamData: async function* () {
|
|
392
|
+
yield 1;
|
|
393
|
+
yield 2;
|
|
394
|
+
yield 3;
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
};
|
|
398
|
+
const factory = createLazy(createTestService, { streamData: 'fn:generator' });
|
|
399
|
+
const service = factory();
|
|
400
|
+
const values = [];
|
|
401
|
+
for await (const value of service.streamData()) {
|
|
402
|
+
values.push(value);
|
|
403
|
+
}
|
|
404
|
+
assert({
|
|
405
|
+
given: 'generator function is called',
|
|
406
|
+
should: 'yield all values from real service',
|
|
407
|
+
actual: values.join(','),
|
|
408
|
+
expected: '1,2,3'
|
|
409
|
+
});
|
|
410
|
+
});
|
|
411
|
+
test('generator function returns same instance', async () => {
|
|
412
|
+
const factory = createLazy(() => Promise.resolve({
|
|
413
|
+
serviceName: 'test-service',
|
|
414
|
+
streamData: async function* () {
|
|
415
|
+
yield 1;
|
|
416
|
+
yield 2;
|
|
417
|
+
}
|
|
418
|
+
}), { streamData: 'fn:generator' });
|
|
419
|
+
const service = factory();
|
|
420
|
+
const fn1 = service.streamData;
|
|
421
|
+
const fn2 = service.streamData;
|
|
422
|
+
assert({
|
|
423
|
+
given: 'generator function property is accessed multiple times',
|
|
424
|
+
should: 'return the same function instance',
|
|
425
|
+
actual: fn1 === fn2,
|
|
426
|
+
expected: true
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
test('generator function calls return different generators', async () => {
|
|
430
|
+
const factory = createLazy(() => Promise.resolve({
|
|
431
|
+
serviceName: 'test-service',
|
|
432
|
+
streamData: async function* (prefix) {
|
|
433
|
+
yield `${prefix}-1`;
|
|
434
|
+
yield `${prefix}-2`;
|
|
435
|
+
}
|
|
436
|
+
}), { streamData: 'fn:generator' });
|
|
437
|
+
const service = factory();
|
|
438
|
+
const gen1 = service.streamData('A');
|
|
439
|
+
const gen2 = service.streamData('B');
|
|
440
|
+
assert({
|
|
441
|
+
given: 'generator function is called multiple times',
|
|
442
|
+
should: 'return different AsyncGenerator instances',
|
|
443
|
+
actual: gen1 !== gen2,
|
|
444
|
+
expected: true
|
|
445
|
+
});
|
|
446
|
+
const values1 = [];
|
|
447
|
+
const values2 = [];
|
|
448
|
+
for await (const value of gen1) {
|
|
449
|
+
values1.push(value);
|
|
450
|
+
}
|
|
451
|
+
for await (const value of gen2) {
|
|
452
|
+
values2.push(value);
|
|
453
|
+
}
|
|
454
|
+
assert({
|
|
455
|
+
given: 'different generator instances with different args',
|
|
456
|
+
should: 'produce independent sequences',
|
|
457
|
+
actual: `${values1.join(',')}|${values2.join(',')}`,
|
|
458
|
+
expected: 'A-1,A-2|B-1,B-2'
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
test('void function returns same instance', async () => {
|
|
462
|
+
const factory = createLazy(() => Promise.resolve({
|
|
463
|
+
serviceName: 'test-service',
|
|
464
|
+
track: (event) => { }
|
|
465
|
+
}), { track: 'fn:void' });
|
|
466
|
+
const service = factory();
|
|
467
|
+
const fn1 = service.track;
|
|
468
|
+
const fn2 = service.track;
|
|
469
|
+
assert({
|
|
470
|
+
given: 'void function property is accessed multiple times',
|
|
471
|
+
should: 'return the same function instance',
|
|
472
|
+
actual: fn1 === fn2,
|
|
473
|
+
expected: true
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
//# sourceMappingURL=create-lazy.test.js.map
|