@equinor/fusion-framework-module-context 8.0.2 → 9.0.0-next.0

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.
Files changed (123) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/README.md +78 -2
  3. package/dist/esm/ContextModuleConfig.js +2 -0
  4. package/dist/esm/ContextModuleConfig.js.map +1 -0
  5. package/dist/esm/ContextModuleConfigurator.interface.js +2 -0
  6. package/dist/esm/ContextModuleConfigurator.interface.js.map +1 -0
  7. package/dist/esm/ContextModuleConfigurator.js +211 -0
  8. package/dist/esm/ContextModuleConfigurator.js.map +1 -0
  9. package/dist/esm/ContextProvider.js +1 -1
  10. package/dist/esm/ContextProvider.js.map +1 -1
  11. package/dist/esm/__tests__/ContextModuleConfigurator.test.js +282 -0
  12. package/dist/esm/__tests__/ContextModuleConfigurator.test.js.map +1 -0
  13. package/dist/esm/__tests__/mock/context-mock.test.js +101 -0
  14. package/dist/esm/__tests__/mock/context-mock.test.js.map +1 -0
  15. package/dist/esm/__tests__/mock/create-context-item-factory.test.js +45 -0
  16. package/dist/esm/__tests__/mock/create-context-item-factory.test.js.map +1 -0
  17. package/dist/esm/__tests__/mock/create-context-items.test.js +46 -0
  18. package/dist/esm/__tests__/mock/create-context-items.test.js.map +1 -0
  19. package/dist/esm/index.js +1 -1
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/mock/ContextMockConfigurator.js +206 -0
  22. package/dist/esm/mock/ContextMockConfigurator.js.map +1 -0
  23. package/dist/esm/mock/fixtures/create-context-item-factory.js +50 -0
  24. package/dist/esm/mock/fixtures/create-context-item-factory.js.map +1 -0
  25. package/dist/esm/mock/fixtures/create-context-items.js +53 -0
  26. package/dist/esm/mock/fixtures/create-context-items.js.map +1 -0
  27. package/dist/esm/mock/fixtures/index.js +22 -0
  28. package/dist/esm/mock/fixtures/index.js.map +1 -0
  29. package/dist/esm/mock/fixtures/string-to-seed.js +15 -0
  30. package/dist/esm/mock/fixtures/string-to-seed.js.map +1 -0
  31. package/dist/esm/mock/index.js +31 -0
  32. package/dist/esm/mock/index.js.map +1 -0
  33. package/dist/esm/mock/module.js +41 -0
  34. package/dist/esm/mock/module.js.map +1 -0
  35. package/dist/esm/module.js +35 -6
  36. package/dist/esm/module.js.map +1 -1
  37. package/dist/esm/{get-context-selector.js → selectors/get-context-selector.js} +1 -4
  38. package/dist/esm/selectors/get-context-selector.js.map +1 -0
  39. package/dist/esm/selectors/index.js +13 -0
  40. package/dist/esm/selectors/index.js.map +1 -0
  41. package/dist/esm/{query-context-selector.js → selectors/query-context-selector.js} +1 -1
  42. package/dist/esm/selectors/query-context-selector.js.map +1 -0
  43. package/dist/esm/{related-context-selector.js → selectors/related-context-selector.js} +1 -1
  44. package/dist/esm/selectors/related-context-selector.js.map +1 -0
  45. package/dist/esm/utils/enable-context.js +1 -1
  46. package/dist/esm/utils/enable-context.js.map +1 -1
  47. package/dist/esm/utils/index.js +2 -0
  48. package/dist/esm/utils/index.js.map +1 -1
  49. package/dist/esm/utils/parse-context-item.js.map +1 -0
  50. package/dist/esm/utils/resolve-initial-context.js +16 -7
  51. package/dist/esm/utils/resolve-initial-context.js.map +1 -1
  52. package/dist/esm/version.js +1 -1
  53. package/dist/esm/version.js.map +1 -1
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist/types/{configurator.d.ts → ContextModuleConfig.d.ts} +4 -64
  56. package/dist/types/ContextModuleConfigurator.d.ts +97 -0
  57. package/dist/types/{ContextConfigBuilder.d.ts → ContextModuleConfigurator.interface.d.ts} +27 -47
  58. package/dist/types/ContextProvider.d.ts +1 -1
  59. package/dist/types/__tests__/ContextModuleConfigurator.test.d.ts +1 -0
  60. package/dist/types/__tests__/mock/context-mock.test.d.ts +1 -0
  61. package/dist/types/__tests__/mock/create-context-item-factory.test.d.ts +1 -0
  62. package/dist/types/__tests__/mock/create-context-items.test.d.ts +1 -0
  63. package/dist/types/index.d.ts +3 -1
  64. package/dist/types/mock/ContextMockConfigurator.d.ts +155 -0
  65. package/dist/types/mock/fixtures/create-context-item-factory.d.ts +40 -0
  66. package/dist/types/mock/fixtures/create-context-items.d.ts +59 -0
  67. package/dist/types/mock/fixtures/index.d.ts +21 -0
  68. package/dist/types/mock/fixtures/string-to-seed.d.ts +12 -0
  69. package/dist/types/mock/index.d.ts +30 -0
  70. package/dist/types/mock/module.d.ts +38 -0
  71. package/dist/types/module.d.ts +5 -3
  72. package/dist/types/{get-context-selector.d.ts → selectors/get-context-selector.d.ts} +1 -3
  73. package/dist/types/selectors/index.d.ts +12 -0
  74. package/dist/types/{query-context-selector.d.ts → selectors/query-context-selector.d.ts} +1 -1
  75. package/dist/types/{related-context-selector.d.ts → selectors/related-context-selector.d.ts} +1 -1
  76. package/dist/types/utils/enable-context.d.ts +4 -5
  77. package/dist/types/utils/index.d.ts +2 -0
  78. package/dist/types/{parse-context-item.d.ts → utils/parse-context-item.d.ts} +1 -1
  79. package/dist/types/utils/resolve-initial-context.d.ts +7 -4
  80. package/dist/types/version.d.ts +1 -1
  81. package/docs/data-model.md +134 -0
  82. package/docs/lifecycle.md +163 -0
  83. package/docs/recipes.md +89 -0
  84. package/package.json +36 -8
  85. package/src/ContextModuleConfig.ts +147 -0
  86. package/src/ContextModuleConfigurator.interface.ts +145 -0
  87. package/src/ContextModuleConfigurator.ts +295 -0
  88. package/src/ContextProvider.ts +1 -2
  89. package/src/__tests__/ContextModuleConfigurator.test.ts +412 -0
  90. package/src/__tests__/mock/context-mock.test.ts +137 -0
  91. package/src/__tests__/mock/create-context-item-factory.test.ts +60 -0
  92. package/src/__tests__/mock/create-context-items.test.ts +58 -0
  93. package/src/index.ts +3 -5
  94. package/src/mock/ContextMockConfigurator.ts +244 -0
  95. package/src/mock/fixtures/create-context-item-factory.ts +62 -0
  96. package/src/mock/fixtures/create-context-items.ts +80 -0
  97. package/src/mock/fixtures/index.ts +28 -0
  98. package/src/mock/fixtures/string-to-seed.ts +18 -0
  99. package/src/mock/index.ts +33 -0
  100. package/src/mock/module.ts +54 -0
  101. package/src/module.ts +45 -17
  102. package/src/{get-context-selector.ts → selectors/get-context-selector.ts} +2 -6
  103. package/src/selectors/index.ts +12 -0
  104. package/src/{query-context-selector.ts → selectors/query-context-selector.ts} +2 -2
  105. package/src/{related-context-selector.ts → selectors/related-context-selector.ts} +2 -2
  106. package/src/utils/enable-context.ts +6 -10
  107. package/src/utils/index.ts +2 -0
  108. package/src/{parse-context-item.ts → utils/parse-context-item.ts} +1 -1
  109. package/src/utils/resolve-initial-context.ts +26 -8
  110. package/src/version.ts +1 -1
  111. package/tsconfig.json +6 -0
  112. package/vitest.config.ts +11 -0
  113. package/dist/esm/ContextConfigBuilder.js +0 -175
  114. package/dist/esm/ContextConfigBuilder.js.map +0 -1
  115. package/dist/esm/configurator.js +0 -99
  116. package/dist/esm/configurator.js.map +0 -1
  117. package/dist/esm/get-context-selector.js.map +0 -1
  118. package/dist/esm/parse-context-item.js.map +0 -1
  119. package/dist/esm/query-context-selector.js.map +0 -1
  120. package/dist/esm/related-context-selector.js.map +0 -1
  121. package/src/ContextConfigBuilder.ts +0 -258
  122. package/src/configurator.ts +0 -295
  123. /package/dist/esm/{parse-context-item.js → utils/parse-context-item.js} +0 -0
@@ -0,0 +1,206 @@
1
+ import { EMPTY, from, lastValueFrom, of, throwError } from 'rxjs';
2
+ import { ContextModuleConfigurator } from '../ContextModuleConfigurator';
3
+ /**
4
+ * A {@link ContextModuleConfigurator} backed by in-memory context items instead
5
+ * of a real context API, for seeding context in tests.
6
+ *
7
+ * @remarks
8
+ * Two layers cover different needs, both running through the real
9
+ * `ContextProvider` logic underneath — only the data source is substituted,
10
+ * never `validateContext`, `resolveContext`, or parent-context propagation:
11
+ *
12
+ * - **Friendly layer** — {@link setCurrentContext}, {@link setContexts},
13
+ * {@link addContext}, {@link setRelatedContexts} — a small, context-domain
14
+ * vocabulary for the common case: seed a known item, get it back.
15
+ * - **Escape hatch** — {@link setResolver} — a raw id-lookup function for a
16
+ * custom id-based resolution strategy or a shape the friendly layer did not
17
+ * cover. Only replaces id-based lookup (used by `setCurrentContextById` and
18
+ * the initial context); it does not affect related-context resolution by
19
+ * item, which always goes through {@link setRelatedContexts} instead.
20
+ *
21
+ * Seeding the initial context (via {@link setCurrentContext}) overrides
22
+ * `resolveInitialContext` directly with the seeded item, so a test never needs
23
+ * to construct a fake navigation module or parent framework instance to make an
24
+ * app start up with a known context selected. Resolving a context id from a URL
25
+ * path on startup is not covered — that needs a fake router, which is separate,
26
+ * not-yet-built work.
27
+ *
28
+ * Seeded ids are never generated for you — every item is looked up and
29
+ * returned exactly by the id it was seeded with, so a test never sees a
30
+ * different id than the one it wrote. Use `createContextItemFactory` or
31
+ * `createContextItems` for fixtures needing ids of their own, rather than a
32
+ * random generator that would change on every run.
33
+ *
34
+ * Related-context resolution defaults to the same seeded pool, filtered to
35
+ * whichever type(s) the query asked for — related context is the same
36
+ * context, just a different type, exactly as `ContextProvider.resolveContext`
37
+ * uses it to resolve an item of an unexpected type into one of the configured
38
+ * type. Seed items of both types and resolution works with no extra wiring;
39
+ * {@link setRelatedContexts} overrides that default for one specific item.
40
+ *
41
+ * @example Seed and select a known context item
42
+ * ```ts
43
+ * enableContextMock(configurator, (mock) => {
44
+ * mock.setCurrentContext({ id: 'my-ctx', type: { id: 'ProjectMaster' }, value: {} });
45
+ * });
46
+ * ```
47
+ *
48
+ * @example Resolve a child-typed item into its parent type
49
+ * ```ts
50
+ * enableContextMock(configurator, (mock) => {
51
+ * // no explicit wiring needed — relatedContexts filters this same pool by type
52
+ * mock.setContexts([project, facility]);
53
+ * });
54
+ * ```
55
+ *
56
+ * @example Override related contexts for one specific item
57
+ * ```ts
58
+ * enableContextMock(configurator, (mock) => {
59
+ * mock.addContext(project);
60
+ * mock.setRelatedContexts(project.id, [facilityA, facilityB]);
61
+ * });
62
+ * ```
63
+ *
64
+ * @example Escape hatch for a custom resolution need
65
+ * ```ts
66
+ * enableContextMock(configurator, (mock) => {
67
+ * mock.setResolver((id) => (id === 'special' ? specialContextItem : undefined));
68
+ * });
69
+ * ```
70
+ */
71
+ export class ContextMockConfigurator extends ContextModuleConfigurator {
72
+ #contexts = new Map();
73
+ #related = new Map();
74
+ #resolver;
75
+ #pendingCurrentId;
76
+ /**
77
+ * Registers the in-memory client up front, so `createConfig` never falls
78
+ * back to building one from a real `ServicesModule` — a mock needs neither
79
+ * an API provider nor a network to answer `get`/`query`/`related`.
80
+ */
81
+ constructor() {
82
+ super();
83
+ this.addConfigBuilder((builder) => {
84
+ builder.setContextClient({
85
+ get: (args) => {
86
+ const item = this.#resolve(args.id);
87
+ // a caller asking for an unseeded id gets a clear error, not a silent miss
88
+ return item
89
+ ? of(item)
90
+ : throwError(() => new Error(`ContextMockConfigurator: no context item resolves for id "${args.id}" — seed it with setCurrentContext/setContexts/addContext, or provide setResolver.`));
91
+ },
92
+ query: () => of([...this.#contexts.values()]),
93
+ related: (args) => {
94
+ const override = this.#related.get(args.item.id);
95
+ // an explicit override for this exact item always wins
96
+ if (override)
97
+ return of(override);
98
+ const types = args.filter?.type;
99
+ // otherwise: related context is the same seeded pool, filtered to the requested type(s)
100
+ return of([...this.#contexts.values()].filter((item) => item.id !== args.item.id && (!types || types.includes(item.type.id))));
101
+ },
102
+ });
103
+ });
104
+ }
105
+ /**
106
+ * Seeds a context item and selects it as the context the app resolves on startup.
107
+ *
108
+ * @param item - The context item to seed and select.
109
+ * @returns This configurator, for chaining.
110
+ */
111
+ setCurrentContext(item) {
112
+ this.#contexts.set(item.id, item);
113
+ this.#pendingCurrentId = item.id;
114
+ return this;
115
+ }
116
+ /**
117
+ * Seeds multiple context items, making each resolvable by id.
118
+ *
119
+ * @remarks
120
+ * Does not select any of them as current — pair with {@link setCurrentContext}
121
+ * for that.
122
+ *
123
+ * @param items - The context items to seed.
124
+ * @returns This configurator, for chaining.
125
+ */
126
+ setContexts(items) {
127
+ // seed every item so each is individually resolvable by id
128
+ for (const item of items)
129
+ this.#contexts.set(item.id, item);
130
+ return this;
131
+ }
132
+ /**
133
+ * Seeds a single context item, making it resolvable by id.
134
+ *
135
+ * @param item - The context item to seed.
136
+ * @returns This configurator, for chaining.
137
+ */
138
+ addContext(item) {
139
+ this.#contexts.set(item.id, item);
140
+ return this;
141
+ }
142
+ /**
143
+ * Overrides related-context resolution for one specific source item.
144
+ *
145
+ * @remarks
146
+ * Without this, `relatedContexts` filters the seeded pool by the requested
147
+ * type(s) — this is only needed when a test wants a specific item to resolve
148
+ * something other than that default (e.g. no related items at all).
149
+ *
150
+ * @param itemId - The id of the item relations are being overridden for.
151
+ * @param items - The context items to return from `relatedContexts` for that item.
152
+ * @returns This configurator, for chaining.
153
+ */
154
+ setRelatedContexts(itemId, items) {
155
+ this.#related.set(itemId, items);
156
+ return this;
157
+ }
158
+ /**
159
+ * Escape hatch: overrides id-based context resolution directly.
160
+ *
161
+ * @remarks
162
+ * For a custom id-lookup strategy or a shape the friendly seeding methods
163
+ * above did not cover — reaching for this means they were already tried
164
+ * and did not fit. Only replaces lookup by id (used by
165
+ * `setCurrentContextById` and the seeded initial context) — related-context
166
+ * resolution by item always goes through {@link setRelatedContexts} instead,
167
+ * regardless of this setting.
168
+ *
169
+ * @param fn - Resolves a context item by id, or returns `undefined` if none matches.
170
+ * @returns This configurator, for chaining.
171
+ */
172
+ setResolver(fn) {
173
+ this.#resolver = fn;
174
+ return this;
175
+ }
176
+ /**
177
+ * Resolves an id through the escape hatch if one is set, otherwise the seeded map.
178
+ *
179
+ * @param id - The context id to resolve.
180
+ * @returns The matching context item, or `undefined`.
181
+ */
182
+ #resolve(id) {
183
+ // the escape hatch, when set, replaces the seeded map entirely
184
+ return this.#resolver ? this.#resolver(id) : this.#contexts.get(id);
185
+ }
186
+ /**
187
+ * Defaults `resolveInitialContext` from the seeded/resolved state, once the
188
+ * real config has been assembled.
189
+ *
190
+ * @param config - The context module config assembled by the base configurator.
191
+ * @param init - Module initializer arguments.
192
+ * @returns The context module configuration, backed by seeded/resolved data.
193
+ */
194
+ async _processConfig(config, init) {
195
+ // the base default is a plain Observable (`of(...)`), not a thenable — unwrap it explicitly
196
+ const resolved = await lastValueFrom(from(super._processConfig(config, init)));
197
+ const id = this.#pendingCurrentId;
198
+ // The base default resolves from the URL path or a parent framework, and
199
+ // throws when neither is present — the common case for an isolated mock.
200
+ // Resolve the seeded item when one was selected, otherwise resolve none.
201
+ resolved.resolveInitialContext = id ? () => of(this.#resolve(id)) : () => EMPTY;
202
+ return resolved;
203
+ }
204
+ }
205
+ export default ContextMockConfigurator;
206
+ //# sourceMappingURL=ContextMockConfigurator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextMockConfigurator.js","sourceRoot":"","sources":["../../../src/mock/ContextMockConfigurator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { Faker, en } from '@faker-js/faker';
2
+ import { stringToSeed } from './string-to-seed';
3
+ /**
4
+ * Builds a {@link MockContextItemFactory} producing deterministic, sequential
5
+ * ids of the form `<prefix>-<n>`, with a realistic `title` filled in by
6
+ * {@link https://fakerjs.dev/ | faker} (`@faker-js/faker`, a peer dependency —
7
+ * only required if this factory is imported).
8
+ *
9
+ * @remarks
10
+ * Ids are scoped to the returned factory, not shared globally, so two tests
11
+ * creating their own factory each start counting from `1` — a random id (e.g.
12
+ * `crypto.randomUUID()`) would change on every run and break any assertion
13
+ * that seeds one item and expects to see that same id again. The faker seed
14
+ * is derived from that same id, so the generated `title` is just as
15
+ * deterministic. For fixtures spanning several context types (e.g. a
16
+ * parent/child type hierarchy), use `createContextItems` instead — it
17
+ * assigns ids per type and wires the type hierarchy for you.
18
+ *
19
+ * @param prefix - The id prefix. Defaults to `'ctx'`.
20
+ * @returns A function creating one {@link ContextItem} fixture per call.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const createContextItem = createContextItemFactory();
25
+ *
26
+ * const project = createContextItem(); // id: 'ctx-1', title: a deterministic faker company name
27
+ * const facility = createContextItem({ title: 'Facility A' }); // id: 'ctx-2', title overridden
28
+ *
29
+ * mock.setContexts([project, facility]);
30
+ * ```
31
+ */
32
+ export const createContextItemFactory = (prefix = 'ctx') => {
33
+ const created = [];
34
+ return (overrides = {}) => {
35
+ // overrides.id, when supplied, always wins over the sequential generator
36
+ const id = overrides.id ?? `${prefix}-${created.length + 1}`;
37
+ const faker = new Faker({ seed: stringToSeed(id), locale: en });
38
+ const item = {
39
+ type: { id: 'Mock' },
40
+ value: {},
41
+ title: faker.company.name(),
42
+ ...overrides,
43
+ id,
44
+ };
45
+ created.push(item);
46
+ return item;
47
+ };
48
+ };
49
+ export default createContextItemFactory;
50
+ //# sourceMappingURL=create-context-item-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-context-item-factory.js","sourceRoot":"","sources":["../../../../src/mock/fixtures/create-context-item-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAWhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,MAAM,GAAG,KAAK,EAA0B,EAAE;IACjF,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,OAAO,CAAC,SAAS,GAAyB,EAAE,EAAe,EAAE;QAC3D,yEAAyE;QACzE,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,IAAI,GAAG,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAChE,MAAM,IAAI,GAAgB;YACxB,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE;YACpB,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;YAC3B,GAAG,SAAS;YACZ,EAAE;SACH,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,53 @@
1
+ import { Faker, en } from '@faker-js/faker';
2
+ import { stringToSeed } from './string-to-seed';
3
+ /**
4
+ * Generates a batch of {@link ContextItem} fixtures across one or more
5
+ * context types, with deterministic ids, a realistic `title` from
6
+ * {@link https://fakerjs.dev/ | faker} (`@faker-js/faker`, a peer dependency —
7
+ * only required if this factory is imported), and a consistent type hierarchy.
8
+ *
9
+ * @remarks
10
+ * Ids are `<type>-<n>` (lowercased type, 1-based per type), so results are
11
+ * stable across runs and readable in test failures. `title` is filled in from
12
+ * a faker instance seeded by that same id, so it's just as deterministic.
13
+ * Feeding the result to `ContextMockConfigurator.setContexts` is enough to
14
+ * make related-context resolution work across types — the mock's
15
+ * `relatedContexts` filters this same seeded pool by type, so a child-typed
16
+ * item resolves into a parent of its `parentTypeIds` without any per-item
17
+ * wiring. That default is a simplification: the real context API resolves
18
+ * relations per specific instance (a `Contract` belongs to one particular
19
+ * `ProjectMaster`, not every `ProjectMaster` in the system) — seed only one
20
+ * instance per type when that distinction doesn't matter to the test, or use
21
+ * `ContextMockConfigurator.setRelatedContexts` to pin a specific item's
22
+ * relations when it does.
23
+ *
24
+ * @param types - The context types, and how many items to generate for each.
25
+ * @returns The generated context items, in the order the type seeds were given.
26
+ *
27
+ * @example Seed a project type and a child contract type
28
+ * ```ts
29
+ * const [project] = createContextItems([{ type: 'ProjectMaster' }]);
30
+ * const [contract] = createContextItems([
31
+ * { type: 'Contract', parentTypeIds: ['ProjectMaster'] },
32
+ * ]);
33
+ *
34
+ * enableContextMock(configurator, (mock) => {
35
+ * mock.setContexts([project, contract]);
36
+ * // relatedContexts({ item: contract, filter: { type: ['ProjectMaster'] } }) now resolves `project`
37
+ * });
38
+ * ```
39
+ */
40
+ export const createContextItems = (types) => types.flatMap(({ type, count = 1, parentTypeIds, item }) => Array.from({ length: count }, (_, i) => {
41
+ const index = i + 1;
42
+ const id = `${type.toLowerCase()}-${index}`;
43
+ const faker = new Faker({ seed: stringToSeed(id), locale: en });
44
+ return {
45
+ value: {},
46
+ title: faker.company.name(),
47
+ ...item?.(index),
48
+ id,
49
+ type: parentTypeIds ? { id: type, isChildType: true, parentTypeIds } : { id: type },
50
+ };
51
+ }));
52
+ export default createContextItems;
53
+ //# sourceMappingURL=create-context-items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-context-items.js","sourceRoot":"","sources":["../../../../src/mock/fixtures/create-context-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAuBhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAwB,EAAiB,EAAE,CAC5E,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,EAAE,CACzD,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAe,EAAE;IAClD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;IACpB,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,KAAK,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAChE,OAAO;QACL,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE;QAC3B,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC;QAChB,EAAE;QACF,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE;KACpF,CAAC;AACJ,CAAC,CAAC,CACH,CAAC;AAEJ,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Fixture generators for {@link ContextMockConfigurator} test data.
3
+ *
4
+ * @remarks
5
+ * A separate entry point from `@equinor/fusion-framework-module-context/mock`
6
+ * because these factories use {@link https://fakerjs.dev/ | faker}
7
+ * (`@faker-js/faker`) for realistic values — an optional peer dependency, only
8
+ * required if this entry point is imported. `enableContextMock` and
9
+ * `ContextMockConfigurator` on the main `/mock` entry point never require it.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { createContextItems } from '@equinor/fusion-framework-module-context/mock/fixtures';
14
+ *
15
+ * const [project] = createContextItems([{ type: 'ProjectMaster' }]);
16
+ * ```
17
+ *
18
+ * @packageDocumentation
19
+ */
20
+ export { createContextItemFactory, } from './create-context-item-factory';
21
+ export { createContextItems, } from './create-context-items';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mock/fixtures/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,wBAAwB,GAEzB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,GAGnB,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Derives a numeric seed from a string, for a deterministic {@link https://fakerjs.dev/ | faker} instance.
3
+ *
4
+ * @remarks
5
+ * A pure-JS hash (no `node:crypto`) so fixtures stay usable in browser-like test
6
+ * environments, not just Node. Same id in, same seed out, every run.
7
+ *
8
+ * @param value - The string to derive a seed from (typically a generated item id).
9
+ * @returns A 32-bit unsigned integer seed.
10
+ */
11
+ export const stringToSeed = (value) =>
12
+ // FNV-1a-style hash: fold each char in, keep the running hash unsigned 32-bit
13
+ [...value].reduce((hash, char) => Math.imul(hash ^ char.charCodeAt(0), 16777619) >>> 0, 2166136261);
14
+ export default stringToSeed;
15
+ //# sourceMappingURL=string-to-seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-to-seed.js","sourceRoot":"","sources":["../../../../src/mock/fixtures/string-to-seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAU,EAAE;AACpD,8EAA8E;AAC9E,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CACf,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,EACpE,UAAU,CACX,CAAC;AAEJ,eAAe,YAAY,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Mock context module for tests: real provider, real configurator, in-memory data.
3
+ *
4
+ * @remarks
5
+ * Substituting the data source is the smallest change that removes the context
6
+ * API, HTTP mocking, and service-discovery mocking from a test. Everything
7
+ * above it — validation, resolution, parent-context propagation, initial-context
8
+ * selection — is the production code path.
9
+ *
10
+ * This is one of two ways to mock context data in tests: a small, static,
11
+ * in-memory pool (this module — no HTTP layer involved at all). The other is
12
+ * mocking the context API's HTTP responses directly (e.g. with MSW), which
13
+ * exercises the real `ContextModuleConfigurator`/services/HTTP pipeline —
14
+ * reach for that instead when the test needs to cover that pipeline itself.
15
+ * For fixture generators with realistic fake data, see
16
+ * `@equinor/fusion-framework-module-context/mock/fixtures`.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { enableContextMock } from '@equinor/fusion-framework-module-context/mock';
21
+ *
22
+ * enableContextMock(configurator, (mock) => {
23
+ * mock.setCurrentContext({ id: 'my-ctx', type: { id: 'ProjectMaster' }, value: {} });
24
+ * });
25
+ * ```
26
+ *
27
+ * @packageDocumentation
28
+ */
29
+ export { ContextMockConfigurator, } from './ContextMockConfigurator';
30
+ export { enableContextMock, contextMockModule } from './module';
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mock/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,EACL,uBAAuB,GAExB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAA4B,MAAM,UAAU,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { module } from '../module';
2
+ import { ContextMockConfigurator } from './ContextMockConfigurator';
3
+ /**
4
+ * The context module with an in-memory mock configurator instead of a real
5
+ * context API.
6
+ *
7
+ * @remarks
8
+ * Only `configure` differs from the real module. `initialize` is the production
9
+ * one, untouched, so a test exercises the real `ContextProvider` startup path,
10
+ * `validateContext`/`resolveContext`, and parent-context propagation — a
11
+ * rehearsal of the module, not a stand-in for it.
12
+ */
13
+ export const contextMockModule = {
14
+ ...module,
15
+ configure: () => new ContextMockConfigurator(),
16
+ };
17
+ /**
18
+ * Enables the context module against in-memory seeded data, so a test needs no
19
+ * context API, no HTTP mock, and no service-discovery mock.
20
+ *
21
+ * @remarks
22
+ * Registered last, this replaces whichever context module the configurator
23
+ * already carries, so it works on a `FrameworkConfigurator` that pre-registers
24
+ * the real one.
25
+ *
26
+ * @param configurator - The modules configurator to register on.
27
+ * @param configure - Optional callback to seed context items or override resolution.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * enableContextMock(configurator, (mock) => {
32
+ * mock.setCurrentContext({ id: 'my-ctx', type: { id: 'ProjectMaster' }, value: {} });
33
+ * });
34
+ * ```
35
+ */
36
+ export const enableContextMock = (
37
+ // biome-ignore lint/suspicious/noExplicitAny: must be any to support all module types
38
+ configurator, configure) => {
39
+ configurator.addConfig({ module: contextMockModule, configure });
40
+ };
41
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../../../src/mock/module.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAsB,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,GAAG,MAAM;IACT,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,uBAAuB,EAAE;CAC/C,CAAC;AAOF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;AAC/B,sFAAsF;AACtF,YAA4C,EAC5C,SAA+B,EACzB,EAAE;IACR,YAAY,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,SAAS,EAE5D,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { catchError, EMPTY, from, Observable, switchMap, filter, Subscription } from 'rxjs';
2
- import { ContextModuleConfigurator } from './configurator';
2
+ import { TelemetryLevel, TelemetryScope, } from '@equinor/fusion-framework-module-telemetry';
3
+ import { ContextModuleConfigurator, } from './ContextModuleConfigurator';
3
4
  import { ContextProvider } from './ContextProvider';
4
5
  /**
5
6
  * Module registration key for the context module.
@@ -34,13 +35,17 @@ export const module = {
34
35
  configure: () => new ContextModuleConfigurator(),
35
36
  initialize: async function (args) {
36
37
  // create config from configurator
37
- const config = await args.config.createConfig(args);
38
+ const config = await args.config.createConfigAsync(args);
38
39
  // get event module if available
39
40
  const event = args.hasModule('event') ? await args.requireInstance('event') : undefined;
41
+ // get telemetry module if available, for tracking context resolution outcomes
42
+ const telemetry = args.hasModule('telemetry')
43
+ ? await args.requireInstance('telemetry')
44
+ : undefined;
40
45
  // get parent context provider if available
41
46
  const parentProvider = args.ref?.context;
42
- // create context provider
43
- const provider = new ContextProvider({ config, event, parentContext: parentProvider });
47
+ // create context provider; parent context is wired up later via connectParentContext, not the deprecated ctor arg
48
+ const provider = new ContextProvider({ config, event });
44
49
  // create subscription for disposing the provider
45
50
  const subscription = new Subscription(() => provider.dispose());
46
51
  // setup post initialize to module
@@ -61,18 +66,42 @@ export const module = {
61
66
  // add teardown to resolve initial context
62
67
  subscriber.add(resolveInitialContext$
63
68
  .pipe(catchError((err) => {
64
- console.warn('ContextModule.postInitialize', 'failed to resolve initial context', err);
69
+ const exception = err instanceof Error ? err : new Error(String(err));
70
+ // report through telemetry when available, otherwise fall back to console.warn below
71
+ if (telemetry) {
72
+ telemetry.trackException({
73
+ name: 'Context::postInitialize.resolveInitialContext',
74
+ exception,
75
+ level: TelemetryLevel.Warning,
76
+ scope: ['context', TelemetryScope.Framework],
77
+ });
78
+ }
79
+ else {
80
+ // no telemetry module registered - fall back to a visible warning so a
81
+ // genuine resolution failure isn't silently swallowed
82
+ console.warn('Context::postInitialize.resolveInitialContext', exception);
83
+ }
65
84
  // failed to resolve initial context, complete immediately
66
85
  return EMPTY;
67
86
  }))
68
87
  .subscribe({
69
88
  next: (item) => {
70
- console.debug('ContextModule.postInitialize', `initial context was resolved to [${item ? item.id : 'none'}]`, item);
89
+ telemetry?.trackEvent({
90
+ name: 'Context::postInitialize.initialContextResolved',
91
+ level: TelemetryLevel.Debug,
92
+ scope: ['context', TelemetryScope.Framework],
93
+ properties: { contextId: item ? item.id : 'none' },
94
+ });
71
95
  },
72
96
  complete: () => {
73
97
  // connect parent context if available when stream completes
74
98
  if (config.connectParentContext !== false && parentProvider) {
75
99
  provider.connectParentContext(parentProvider);
100
+ telemetry?.trackEvent({
101
+ name: 'Context::postInitialize.parentContextConnected',
102
+ level: TelemetryLevel.Debug,
103
+ scope: ['context', TelemetryScope.Framework],
104
+ });
76
105
  }
77
106
  subscriber.complete();
78
107
  },
@@ -1 +1 @@
1
- {"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { parseContextItem } from './parse-context-item';
1
+ import { parseContextItem } from '../utils/parse-context-item';
2
2
  /**
3
3
  * Parse the response from the GetContext API into a context item.
4
4
  * @param response The response object containing the context item.
@@ -8,7 +8,4 @@ export const getContextSelector = async (response) => {
8
8
  const result = (await response.json());
9
9
  return parseContextItem(result);
10
10
  };
11
- // Deliberately re-exported from here to preserve the package's existing selectors entry point
12
- export { queryContextSelector } from './query-context-selector';
13
- export { relatedContextSelector } from './related-context-selector';
14
11
  //# sourceMappingURL=get-context-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-context-selector.js","sourceRoot":"","sources":["../../../src/selectors/get-context-selector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,QAAkB,EAAwB,EAAE;IACnF,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA6B,CAAC;IACnE,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAClC,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Response selectors that parse raw context API responses into {@link ContextItem}s.
3
+ *
4
+ * - {@link getContextSelector} — parses a single-item GetContext response.
5
+ * - {@link queryContextSelector} — parses a multi-item QueryContext response.
6
+ * - {@link relatedContextSelector} — parses a multi-item RelatedContext response.
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ export { getContextSelector } from './get-context-selector';
11
+ export { queryContextSelector } from './query-context-selector';
12
+ export { relatedContextSelector } from './related-context-selector';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/selectors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { parseContextItem } from './parse-context-item';
1
+ import { parseContextItem } from '../utils/parse-context-item';
2
2
  /**
3
3
  * Parse the response from the QueryContext API into an array of context items.
4
4
  * @param response The response object.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-context-selector.js","sourceRoot":"","sources":["../../../src/selectors/query-context-selector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,QAAkB,EAA0B,EAAE;IACvF,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA+B,CAAC;IACrE,8CAA8C;IAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACtC,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { parseContextItem } from './parse-context-item';
1
+ import { parseContextItem } from '../utils/parse-context-item';
2
2
  /**
3
3
  * Parse the response from the RelatedContext API into an array of context items.
4
4
  * @param response The response object containing the related context items.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"related-context-selector.js","sourceRoot":"","sources":["../../../src/selectors/related-context-selector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAG/D;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,QAAkB,EAA0B,EAAE;IACzF,MAAM,MAAM,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAiC,CAAC;IACvE,8CAA8C;IAC9C,OAAO,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACtC,CAAC,CAAC"}
@@ -3,7 +3,7 @@ import { module } from '../module';
3
3
  * Enables context configuration for a given modules configurator.
4
4
  *
5
5
  * @param configurator - The modules configurator instance to which the context module will be added.
6
- * @param builder - An optional function that receives a context configuration builder. This function can be used to further configure the context module. It can be asynchronous.
6
+ * @param builder - An optional function that receives the {@link IContextModuleConfigurator}. This function can be used to further configure the context module. It can be asynchronous.
7
7
  *
8
8
  * @remarks
9
9
  * This utility function adds the context module to the provided configurator and optionally applies additional configuration using the provided builder function.
@@ -1 +1 @@
1
- {"version":3,"file":"enable-context.js","sourceRoot":"","sources":["../../../src/utils/enable-context.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;AAC3B,sFAAsF;AACtF,YAA4C,EAC5C,OAEyB,EACnB,EAAE;IACR,YAAY,CAAC,SAAS,CAAC;QACrB,MAAM;QACN,SAAS,EAAE,CAAC,mBAAmB,EAAE,EAAE;YACjC,OAAO,IAAI,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
1
+ {"version":3,"file":"enable-context.js","sourceRoot":"","sources":["../../../src/utils/enable-context.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;AAC3B,sFAAsF;AACtF,YAA4C,EAC5C,OAAsC,EAChC,EAAE;IACR,YAAY,CAAC,SAAS,CAAC;QACrB,MAAM;QACN,SAAS,EAAE,CAAC,mBAAmB,EAAE,EAAE;YACjC,OAAO,IAAI,mBAAmB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC;KACF,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -5,10 +5,12 @@
5
5
  * - {@link resolveInitialContext} — default initial-context resolver (path → parent fallback).
6
6
  * - {@link extractContextIdFromPath} — extract a GUID context ID from a URL path.
7
7
  * - {@link resolveContextFromPath} — resolve a context item from a URL path.
8
+ * - {@link parseContextItem} — parse a raw API context entity into a `ContextItem`.
8
9
  *
9
10
  * @packageDocumentation
10
11
  */
11
12
  export { enableContext } from './enable-context';
12
13
  export { resolveInitialContext } from './resolve-initial-context';
13
14
  export { extractContextIdFromPath, resolveContextFromPath } from './resolve-context-from-path';
15
+ export { parseContextItem } from './parse-context-item';
14
16
  //# sourceMappingURL=index.js.map