@contentful/optimization-core 0.1.0-alpha

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 (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -0
  3. package/dist/Consent.d.ts +44 -0
  4. package/dist/Consent.d.ts.map +1 -0
  5. package/dist/Consent.js +2 -0
  6. package/dist/Consent.js.map +1 -0
  7. package/dist/CoreBase.d.ts +161 -0
  8. package/dist/CoreBase.d.ts.map +1 -0
  9. package/dist/CoreBase.js +151 -0
  10. package/dist/CoreBase.js.map +1 -0
  11. package/dist/CoreStateful.d.ts +142 -0
  12. package/dist/CoreStateful.d.ts.map +1 -0
  13. package/dist/CoreStateful.js +137 -0
  14. package/dist/CoreStateful.js.map +1 -0
  15. package/dist/CoreStateless.d.ts +53 -0
  16. package/dist/CoreStateless.d.ts.map +1 -0
  17. package/dist/CoreStateless.js +43 -0
  18. package/dist/CoreStateless.js.map +1 -0
  19. package/dist/ProductBase.d.ts +83 -0
  20. package/dist/ProductBase.d.ts.map +1 -0
  21. package/dist/ProductBase.js +50 -0
  22. package/dist/ProductBase.js.map +1 -0
  23. package/dist/analytics/AnalyticsBase.d.ts +35 -0
  24. package/dist/analytics/AnalyticsBase.d.ts.map +1 -0
  25. package/dist/analytics/AnalyticsBase.js +13 -0
  26. package/dist/analytics/AnalyticsBase.js.map +1 -0
  27. package/dist/analytics/AnalyticsStateful.d.ts +138 -0
  28. package/dist/analytics/AnalyticsStateful.d.ts.map +1 -0
  29. package/dist/analytics/AnalyticsStateful.js +179 -0
  30. package/dist/analytics/AnalyticsStateful.js.map +1 -0
  31. package/dist/analytics/AnalyticsStateless.d.ts +48 -0
  32. package/dist/analytics/AnalyticsStateless.d.ts.map +1 -0
  33. package/dist/analytics/AnalyticsStateless.js +61 -0
  34. package/dist/analytics/AnalyticsStateless.js.map +1 -0
  35. package/dist/analytics/index.d.ts +5 -0
  36. package/dist/analytics/index.d.ts.map +1 -0
  37. package/dist/analytics/index.js +5 -0
  38. package/dist/analytics/index.js.map +1 -0
  39. package/dist/global-constants.d.ts +18 -0
  40. package/dist/global-constants.d.ts.map +1 -0
  41. package/dist/global-constants.js +18 -0
  42. package/dist/global-constants.js.map +1 -0
  43. package/dist/index.cjs +1808 -0
  44. package/dist/index.cjs.map +1 -0
  45. package/dist/index.d.ts +15 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +15 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/index.mjs +1535 -0
  50. package/dist/index.mjs.map +1 -0
  51. package/dist/lib/decorators/guardedBy.d.ts +113 -0
  52. package/dist/lib/decorators/guardedBy.d.ts.map +1 -0
  53. package/dist/lib/decorators/guardedBy.js +143 -0
  54. package/dist/lib/decorators/guardedBy.js.map +1 -0
  55. package/dist/lib/decorators/index.d.ts +2 -0
  56. package/dist/lib/decorators/index.d.ts.map +1 -0
  57. package/dist/lib/decorators/index.js +2 -0
  58. package/dist/lib/decorators/index.js.map +1 -0
  59. package/dist/lib/interceptor/InterceptorManager.d.ts +127 -0
  60. package/dist/lib/interceptor/InterceptorManager.d.ts.map +1 -0
  61. package/dist/lib/interceptor/InterceptorManager.js +125 -0
  62. package/dist/lib/interceptor/InterceptorManager.js.map +1 -0
  63. package/dist/lib/interceptor/index.d.ts +2 -0
  64. package/dist/lib/interceptor/index.d.ts.map +1 -0
  65. package/dist/lib/interceptor/index.js +2 -0
  66. package/dist/lib/interceptor/index.js.map +1 -0
  67. package/dist/lib/value-presence/ValuePresence.d.ts +123 -0
  68. package/dist/lib/value-presence/ValuePresence.d.ts.map +1 -0
  69. package/dist/lib/value-presence/ValuePresence.js +141 -0
  70. package/dist/lib/value-presence/ValuePresence.js.map +1 -0
  71. package/dist/lib/value-presence/index.d.ts +2 -0
  72. package/dist/lib/value-presence/index.d.ts.map +1 -0
  73. package/dist/lib/value-presence/index.js +2 -0
  74. package/dist/lib/value-presence/index.js.map +1 -0
  75. package/dist/personalization/PersonalizationBase.d.ts +184 -0
  76. package/dist/personalization/PersonalizationBase.d.ts.map +1 -0
  77. package/dist/personalization/PersonalizationBase.js +76 -0
  78. package/dist/personalization/PersonalizationBase.js.map +1 -0
  79. package/dist/personalization/PersonalizationStateful.d.ts +226 -0
  80. package/dist/personalization/PersonalizationStateful.d.ts.map +1 -0
  81. package/dist/personalization/PersonalizationStateful.js +297 -0
  82. package/dist/personalization/PersonalizationStateful.js.map +1 -0
  83. package/dist/personalization/PersonalizationStateless.d.ts +74 -0
  84. package/dist/personalization/PersonalizationStateless.d.ts.map +1 -0
  85. package/dist/personalization/PersonalizationStateless.js +98 -0
  86. package/dist/personalization/PersonalizationStateless.js.map +1 -0
  87. package/dist/personalization/index.d.ts +6 -0
  88. package/dist/personalization/index.d.ts.map +1 -0
  89. package/dist/personalization/index.js +6 -0
  90. package/dist/personalization/index.js.map +1 -0
  91. package/dist/personalization/resolvers/FlagsResolver.d.ts +35 -0
  92. package/dist/personalization/resolvers/FlagsResolver.d.ts.map +1 -0
  93. package/dist/personalization/resolvers/FlagsResolver.js +47 -0
  94. package/dist/personalization/resolvers/FlagsResolver.js.map +1 -0
  95. package/dist/personalization/resolvers/MergeTagValueResolver.d.ts +74 -0
  96. package/dist/personalization/resolvers/MergeTagValueResolver.d.ts.map +1 -0
  97. package/dist/personalization/resolvers/MergeTagValueResolver.js +109 -0
  98. package/dist/personalization/resolvers/MergeTagValueResolver.js.map +1 -0
  99. package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts +142 -0
  100. package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts.map +1 -0
  101. package/dist/personalization/resolvers/PersonalizedEntryResolver.js +196 -0
  102. package/dist/personalization/resolvers/PersonalizedEntryResolver.js.map +1 -0
  103. package/dist/personalization/resolvers/index.d.ts +7 -0
  104. package/dist/personalization/resolvers/index.d.ts.map +1 -0
  105. package/dist/personalization/resolvers/index.js +7 -0
  106. package/dist/personalization/resolvers/index.js.map +1 -0
  107. package/dist/signals.d.ts +35 -0
  108. package/dist/signals.d.ts.map +1 -0
  109. package/dist/signals.js +30 -0
  110. package/dist/signals.js.map +1 -0
  111. package/package.json +29 -0
@@ -0,0 +1,127 @@
1
+ /**
2
+ * A utility type representing a value that may be synchronously available or
3
+ * produced asynchronously.
4
+ *
5
+ * @typeParam T - The resolved value type.
6
+ * @public
7
+ */
8
+ type MaybePromise<T> = T | Promise<T>;
9
+ /**
10
+ * A function that receives a value of type `T` and returns a (possibly async)
11
+ * value of the same type `T`. The input is marked as `readonly` to discourage
12
+ * mutation of the original object.
13
+ *
14
+ * @typeParam T - The value type intercepted and returned.
15
+ * @param value - The current (readonly) value in the interception chain.
16
+ * @returns The next value for the chain, either directly or via a promise.
17
+ * @remarks Implementations SHOULD avoid mutating `value` and instead return a
18
+ * new or safely-updated instance.
19
+ * @see {@link InterceptorManager}
20
+ * @public
21
+ */
22
+ export type Interceptor<T> = (value: Readonly<T>) => MaybePromise<T>;
23
+ /**
24
+ * Manages a list of interceptors and provides a way to run them in sequence.
25
+ *
26
+ * Interceptors are executed in insertion order. Each interceptor receives the
27
+ * result of the previous interceptor (or the initial input for the first one)
28
+ * and may return a new value synchronously or asynchronously.
29
+ *
30
+ * @typeParam T - The value type processed by the interceptors.
31
+ * @remarks This class snapshots the current interceptor list at invocation time
32
+ * so additions/removals during `run` do not affect the in-flight execution.
33
+ * @example
34
+ * ```ts
35
+ * const mgr = new InterceptorManager<number>();
36
+ * const id = mgr.add((n) => n + 1);
37
+ * const final = await mgr.run(1); // 2
38
+ * mgr.remove(id);
39
+ * ```
40
+ * @public
41
+ */
42
+ export declare class InterceptorManager<T> {
43
+ /**
44
+ * The registry of interceptors keyed by their insertion id.
45
+ *
46
+ * @privateRemarks Internal storage; use {@link add}, {@link remove}, and
47
+ * {@link clear} to manage contents.
48
+ * @readonly
49
+ * @defaultValue `new Map()`
50
+ */
51
+ private readonly interceptors;
52
+ /**
53
+ * The next numeric id to assign to an added interceptor.
54
+ *
55
+ * @privateRemarks Used only to generate unique, monotonically increasing ids.
56
+ * @defaultValue `0`
57
+ */
58
+ private nextId;
59
+ /**
60
+ * Add an interceptor and return its identifier.
61
+ *
62
+ * @param interceptor - The interceptor function to register.
63
+ * @returns The numeric id that can later be used with {@link remove}.
64
+ * @remarks Interceptors are executed in the order they are added.
65
+ * @example
66
+ * ```ts
67
+ * const id = manager.add(async (value) => transform(value));
68
+ * ```
69
+ * @public
70
+ */
71
+ add(interceptor: Interceptor<T>): number;
72
+ /**
73
+ * Remove an interceptor by its identifier.
74
+ *
75
+ * @param id - The id previously returned by {@link add}.
76
+ * @returns `true` if an interceptor was removed; otherwise `false`.
77
+ * @example
78
+ * ```ts
79
+ * const removed = manager.remove(id);
80
+ * ```
81
+ * @public
82
+ */
83
+ remove(id: number): boolean;
84
+ /**
85
+ * Remove all registered interceptors.
86
+ *
87
+ * @returns Nothing.
88
+ * @remarks After calling this, {@link count} will return `0`.
89
+ * @example
90
+ * ```ts
91
+ * manager.clear();
92
+ * ```
93
+ * @public
94
+ */
95
+ clear(): void;
96
+ /**
97
+ * Get the number of currently registered interceptors.
98
+ *
99
+ * @returns The count of interceptors.
100
+ * @example
101
+ * ```ts
102
+ * if (manager.count() === 0) { /* ... *\/ }
103
+ * ```
104
+ * @public
105
+ */
106
+ count(): number;
107
+ /**
108
+ * Run all interceptors in sequence on an input value and return the final result.
109
+ *
110
+ * Supports both sync and async interceptors; the return type is always `Promise<T>`
111
+ * for consistency.
112
+ *
113
+ * @param input - The initial value to pass to the first interceptor.
114
+ * @returns A promise resolving to the final value after all interceptors have run.
115
+ * @throws May rethrow any error thrown by an interceptor. <!-- Intentionally vague: error type depends on interceptor implementation -->
116
+ * @remarks The interceptor list is snapshotted at invocation time; changes to
117
+ * the registry during execution do not affect the running sequence.
118
+ * @example
119
+ * ```ts
120
+ * const result = await manager.run(initial);
121
+ * ```
122
+ * @public
123
+ */
124
+ run(input: T): Promise<T>;
125
+ }
126
+ export {};
127
+ //# sourceMappingURL=InterceptorManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InterceptorManager.d.ts","sourceRoot":"","sources":["../../../src/lib/interceptor/InterceptorManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;AAErC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,CAAA;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,kBAAkB,CAAC,CAAC;IAC/B;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoC;IAEjE;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAI;IAElB;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM;IAOxC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B;;;;;;;;;;OAUG;IACH,KAAK,IAAI,IAAI;IAIb;;;;;;;;;OASG;IACH,KAAK,IAAI,MAAM;IAIf;;;;;;;;;;;;;;;;OAgBG;IACG,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAchC"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Manages a list of interceptors and provides a way to run them in sequence.
3
+ *
4
+ * Interceptors are executed in insertion order. Each interceptor receives the
5
+ * result of the previous interceptor (or the initial input for the first one)
6
+ * and may return a new value synchronously or asynchronously.
7
+ *
8
+ * @typeParam T - The value type processed by the interceptors.
9
+ * @remarks This class snapshots the current interceptor list at invocation time
10
+ * so additions/removals during `run` do not affect the in-flight execution.
11
+ * @example
12
+ * ```ts
13
+ * const mgr = new InterceptorManager<number>();
14
+ * const id = mgr.add((n) => n + 1);
15
+ * const final = await mgr.run(1); // 2
16
+ * mgr.remove(id);
17
+ * ```
18
+ * @public
19
+ */
20
+ export class InterceptorManager {
21
+ /**
22
+ * The registry of interceptors keyed by their insertion id.
23
+ *
24
+ * @privateRemarks Internal storage; use {@link add}, {@link remove}, and
25
+ * {@link clear} to manage contents.
26
+ * @readonly
27
+ * @defaultValue `new Map()`
28
+ */
29
+ interceptors = new Map();
30
+ /**
31
+ * The next numeric id to assign to an added interceptor.
32
+ *
33
+ * @privateRemarks Used only to generate unique, monotonically increasing ids.
34
+ * @defaultValue `0`
35
+ */
36
+ nextId = 0;
37
+ /**
38
+ * Add an interceptor and return its identifier.
39
+ *
40
+ * @param interceptor - The interceptor function to register.
41
+ * @returns The numeric id that can later be used with {@link remove}.
42
+ * @remarks Interceptors are executed in the order they are added.
43
+ * @example
44
+ * ```ts
45
+ * const id = manager.add(async (value) => transform(value));
46
+ * ```
47
+ * @public
48
+ */
49
+ add(interceptor) {
50
+ const { nextId: id } = this;
51
+ this.nextId += 1;
52
+ this.interceptors.set(id, interceptor);
53
+ return id;
54
+ }
55
+ /**
56
+ * Remove an interceptor by its identifier.
57
+ *
58
+ * @param id - The id previously returned by {@link add}.
59
+ * @returns `true` if an interceptor was removed; otherwise `false`.
60
+ * @example
61
+ * ```ts
62
+ * const removed = manager.remove(id);
63
+ * ```
64
+ * @public
65
+ */
66
+ remove(id) {
67
+ return this.interceptors.delete(id);
68
+ }
69
+ /**
70
+ * Remove all registered interceptors.
71
+ *
72
+ * @returns Nothing.
73
+ * @remarks After calling this, {@link count} will return `0`.
74
+ * @example
75
+ * ```ts
76
+ * manager.clear();
77
+ * ```
78
+ * @public
79
+ */
80
+ clear() {
81
+ this.interceptors.clear();
82
+ }
83
+ /**
84
+ * Get the number of currently registered interceptors.
85
+ *
86
+ * @returns The count of interceptors.
87
+ * @example
88
+ * ```ts
89
+ * if (manager.count() === 0) { /* ... *\/ }
90
+ * ```
91
+ * @public
92
+ */
93
+ count() {
94
+ return this.interceptors.size;
95
+ }
96
+ /**
97
+ * Run all interceptors in sequence on an input value and return the final result.
98
+ *
99
+ * Supports both sync and async interceptors; the return type is always `Promise<T>`
100
+ * for consistency.
101
+ *
102
+ * @param input - The initial value to pass to the first interceptor.
103
+ * @returns A promise resolving to the final value after all interceptors have run.
104
+ * @throws May rethrow any error thrown by an interceptor. <!-- Intentionally vague: error type depends on interceptor implementation -->
105
+ * @remarks The interceptor list is snapshotted at invocation time; changes to
106
+ * the registry during execution do not affect the running sequence.
107
+ * @example
108
+ * ```ts
109
+ * const result = await manager.run(initial);
110
+ * ```
111
+ * @public
112
+ */
113
+ async run(input) {
114
+ // Snapshot to avoid issues if interceptors are added/removed during execution.
115
+ const fns = Array.from(this.interceptors.values());
116
+ let acc = input;
117
+ for (const fn of fns) {
118
+ // Pass a readonly view to discourage mutation of intermediate values.
119
+ // Each interceptor must return a T (or Promise<T>).
120
+ acc = await fn(acc);
121
+ }
122
+ return acc;
123
+ }
124
+ }
125
+ //# sourceMappingURL=InterceptorManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InterceptorManager.js","sourceRoot":"","sources":["../../../src/lib/interceptor/InterceptorManager.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;;;;;;OAOG;IACc,YAAY,GAAG,IAAI,GAAG,EAA0B,CAAA;IAEjE;;;;;OAKG;IACK,MAAM,GAAG,CAAC,CAAA;IAElB;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,WAA2B;QAC7B,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,CAAA;QAC3B,IAAI,CAAC,MAAM,IAAI,CAAC,CAAA;QAChB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,CAAA;QACtC,OAAO,EAAE,CAAA;IACX,CAAC;IAED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAU;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACrC,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK;QACH,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;IAC3B,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK;QACH,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAA;IAC/B,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,GAAG,CAAC,KAAQ;QAChB,+EAA+E;QAC/E,MAAM,GAAG,GAAkC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAA;QAEjF,IAAI,GAAG,GAAM,KAAK,CAAA;QAElB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,sEAAsE;YACtE,oDAAoD;YACpD,GAAG,GAAG,MAAM,EAAE,CAAC,GAAkB,CAAC,CAAA;QACpC,CAAC;QAED,OAAO,GAAG,CAAA;IACZ,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export * from './InterceptorManager';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/interceptor/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './InterceptorManager';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/interceptor/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * A scope identifier for grouping values.
3
+ *
4
+ * @remarks
5
+ * Use a non-empty string for a named scope. Use `undefined` for the
6
+ * "global/default" scope. An empty string (`""`) passed to the constructor
7
+ * initializer is normalized to `undefined`.
8
+ *
9
+ * @public
10
+ */
11
+ type ValuePresenceScope = string | undefined;
12
+ /**
13
+ * Tracks whether a given value is present within one or more logical scopes.
14
+ *
15
+ * @remarks
16
+ * - Scope names are case-sensitive.
17
+ * - Presence is based on `Set.has` reference equality for objects and
18
+ * value equality for primitives.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const presence = new ValuePresence({ default: ['a', 'b'] })
23
+ * presence.isPresent('default', 'a') // true
24
+ * presence.addValue('default', 'c')
25
+ * presence.removeValue('default', 'b')
26
+ * presence.reset('default')
27
+ * ```
28
+ *
29
+ * @see {@link ValuePresenceScope}
30
+ * @public
31
+ */
32
+ declare class ValuePresence {
33
+ #private;
34
+ /**
35
+ * Create a new {@link ValuePresence}.
36
+ *
37
+ * @param defaultMap - Optional initial data. Keys are scope names; values are arrays of items to seed.
38
+ * Empty-string keys are normalized to the default scope (`undefined`).
39
+ *
40
+ * @remarks
41
+ * - If `defaultMap` contains duplicate items for a scope, duplicates are collapsed by the `Set`.
42
+ */
43
+ constructor(defaultMap?: Record<string, unknown[]>);
44
+ /**
45
+ * Check whether a value is present within a given scope.
46
+ *
47
+ * @param scope - The scope to check. Use `undefined` for the default scope.
48
+ * @param value - The value to test for presence.
49
+ * @returns `true` if the value is present in the specified scope; otherwise `false`.
50
+ *
51
+ * @remarks
52
+ * Presence testing uses `Set.prototype.has` semantics.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * presence.isPresent(undefined, 42) // e.g., true or false
57
+ * ```
58
+ *
59
+ * @public
60
+ */
61
+ isPresent(scope: ValuePresenceScope, value: unknown): boolean;
62
+ /**
63
+ * Add a value to a scope, creating the scope if it does not exist.
64
+ *
65
+ * @param scope - Scope to add the value to. Use `undefined` for the default scope.
66
+ * @param value - The value to add.
67
+ * @returns void
68
+ *
69
+ * @remarks
70
+ * - No-op if the value is already present (due to `Set` semantics).
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * presence.addValue('users', userId)
75
+ * ```
76
+ *
77
+ * @public
78
+ */
79
+ addValue(scope: ValuePresenceScope, value: unknown): void;
80
+ /**
81
+ * Remove a value from a scope.
82
+ *
83
+ * @param scope - Scope to remove from. Use `undefined` for the default scope.
84
+ * @param value - The value to remove.
85
+ * @returns void
86
+ *
87
+ * @remarks
88
+ * If the scope does not exist or the value is not present, this is a no-op.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * presence.removeValue('users', userId)
93
+ * ```
94
+ *
95
+ * @public
96
+ */
97
+ removeValue(scope: ValuePresenceScope, value: unknown): void;
98
+ /**
99
+ * Clear values from a single scope, or from all scopes.
100
+ *
101
+ * @param scope - If provided, clears only that scope. If omitted, clears all scopes.
102
+ * @returns void
103
+ *
104
+ * @remarks
105
+ * - When called with a specific scope that does not exist, this is a no-op.
106
+ * - When called with no arguments, all scopes and values are removed.
107
+ * - Clearing a non-existent scope will not create the scope.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * // Clear one scope
112
+ * presence.reset('users')
113
+ *
114
+ * // Clear all scopes
115
+ * presence.reset()
116
+ * ```
117
+ *
118
+ * @public
119
+ */
120
+ reset(scope?: ValuePresenceScope): void;
121
+ }
122
+ export default ValuePresence;
123
+ //# sourceMappingURL=ValuePresence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValuePresence.d.ts","sourceRoot":"","sources":["../../../src/lib/value-presence/ValuePresence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,KAAK,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAAA;AAE5C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,cAAM,aAAa;;IAQjB;;;;;;;;OAQG;gBACS,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IAWlD;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;IAI7D;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAUzD;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,CAAC,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAI5D;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,KAAK,CAAC,EAAE,kBAAkB,GAAG,IAAI;CAOxC;AAED,eAAe,aAAa,CAAA"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Tracks whether a given value is present within one or more logical scopes.
3
+ *
4
+ * @remarks
5
+ * - Scope names are case-sensitive.
6
+ * - Presence is based on `Set.has` reference equality for objects and
7
+ * value equality for primitives.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const presence = new ValuePresence({ default: ['a', 'b'] })
12
+ * presence.isPresent('default', 'a') // true
13
+ * presence.addValue('default', 'c')
14
+ * presence.removeValue('default', 'b')
15
+ * presence.reset('default')
16
+ * ```
17
+ *
18
+ * @see {@link ValuePresenceScope}
19
+ * @public
20
+ */
21
+ class ValuePresence {
22
+ /**
23
+ * Internal map of scope -> set of values present in that scope.
24
+ *
25
+ * @internal
26
+ */
27
+ #map;
28
+ /**
29
+ * Create a new {@link ValuePresence}.
30
+ *
31
+ * @param defaultMap - Optional initial data. Keys are scope names; values are arrays of items to seed.
32
+ * Empty-string keys are normalized to the default scope (`undefined`).
33
+ *
34
+ * @remarks
35
+ * - If `defaultMap` contains duplicate items for a scope, duplicates are collapsed by the `Set`.
36
+ */
37
+ constructor(defaultMap) {
38
+ const map = new Map();
39
+ if (defaultMap)
40
+ Object.entries(defaultMap).map(([scope, values]) => map.set(scope.length ? scope : undefined, new Set(values)));
41
+ this.#map = map;
42
+ }
43
+ /**
44
+ * Check whether a value is present within a given scope.
45
+ *
46
+ * @param scope - The scope to check. Use `undefined` for the default scope.
47
+ * @param value - The value to test for presence.
48
+ * @returns `true` if the value is present in the specified scope; otherwise `false`.
49
+ *
50
+ * @remarks
51
+ * Presence testing uses `Set.prototype.has` semantics.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * presence.isPresent(undefined, 42) // e.g., true or false
56
+ * ```
57
+ *
58
+ * @public
59
+ */
60
+ isPresent(scope, value) {
61
+ return this.#map.get(scope)?.has(value) ?? false;
62
+ }
63
+ /**
64
+ * Add a value to a scope, creating the scope if it does not exist.
65
+ *
66
+ * @param scope - Scope to add the value to. Use `undefined` for the default scope.
67
+ * @param value - The value to add.
68
+ * @returns void
69
+ *
70
+ * @remarks
71
+ * - No-op if the value is already present (due to `Set` semantics).
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * presence.addValue('users', userId)
76
+ * ```
77
+ *
78
+ * @public
79
+ */
80
+ addValue(scope, value) {
81
+ const values = this.#map.get(scope);
82
+ if (!values) {
83
+ this.#map.set(scope, new Set([value]));
84
+ }
85
+ else {
86
+ values.add(value);
87
+ }
88
+ }
89
+ /**
90
+ * Remove a value from a scope.
91
+ *
92
+ * @param scope - Scope to remove from. Use `undefined` for the default scope.
93
+ * @param value - The value to remove.
94
+ * @returns void
95
+ *
96
+ * @remarks
97
+ * If the scope does not exist or the value is not present, this is a no-op.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * presence.removeValue('users', userId)
102
+ * ```
103
+ *
104
+ * @public
105
+ */
106
+ removeValue(scope, value) {
107
+ this.#map.get(scope)?.delete(value);
108
+ }
109
+ /**
110
+ * Clear values from a single scope, or from all scopes.
111
+ *
112
+ * @param scope - If provided, clears only that scope. If omitted, clears all scopes.
113
+ * @returns void
114
+ *
115
+ * @remarks
116
+ * - When called with a specific scope that does not exist, this is a no-op.
117
+ * - When called with no arguments, all scopes and values are removed.
118
+ * - Clearing a non-existent scope will not create the scope.
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * // Clear one scope
123
+ * presence.reset('users')
124
+ *
125
+ * // Clear all scopes
126
+ * presence.reset()
127
+ * ```
128
+ *
129
+ * @public
130
+ */
131
+ reset(scope) {
132
+ if (scope !== undefined) {
133
+ this.#map.get(scope)?.clear();
134
+ }
135
+ else {
136
+ this.#map.clear();
137
+ }
138
+ }
139
+ }
140
+ export default ValuePresence;
141
+ //# sourceMappingURL=ValuePresence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValuePresence.js","sourceRoot":"","sources":["../../../src/lib/value-presence/ValuePresence.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,aAAa;IACjB;;;;OAIG;IACM,IAAI,CAAuC;IAEpD;;;;;;;;OAQG;IACH,YAAY,UAAsC;QAChD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAoC,CAAA;QAEvD,IAAI,UAAU;YACZ,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,CACjD,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAC3D,CAAA;QAEH,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;IACjB,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,KAAyB,EAAE,KAAc;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAA;IAClD,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,KAAyB,EAAE,KAAc;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAEnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACxC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACnB,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,WAAW,CAAC,KAAyB,EAAE,KAAc;QACnD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,KAA0B;QAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAA;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;QACnB,CAAC;IACH,CAAC;CACF;AAED,eAAe,aAAa,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { default as ValuePresence } from './ValuePresence';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/value-presence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { default as ValuePresence } from './ValuePresence';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/value-presence/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,iBAAiB,CAAA"}