@croct/sdk 0.17.10 → 0.17.11

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 (108) hide show
  1. package/constants.cjs +1 -1
  2. package/constants.cjs.map +1 -1
  3. package/constants.d.ts +2 -2
  4. package/constants.js +1 -1
  5. package/constants.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/activeRecord.ts +0 -150
  8. package/src/apiKey.ts +0 -208
  9. package/src/base64Url.ts +0 -22
  10. package/src/cache/cache.ts +0 -22
  11. package/src/cache/cookieCache.ts +0 -88
  12. package/src/cache/fallbackCache.ts +0 -29
  13. package/src/cache/inMemoryCache.ts +0 -21
  14. package/src/cache/index.ts +0 -4
  15. package/src/cache/localStorageCache.ts +0 -85
  16. package/src/channel/channel.ts +0 -52
  17. package/src/channel/encodedChannel.ts +0 -21
  18. package/src/channel/guaranteedChannel.ts +0 -131
  19. package/src/channel/httpBeaconChannel.ts +0 -128
  20. package/src/channel/index.ts +0 -7
  21. package/src/channel/queuedChannel.ts +0 -143
  22. package/src/channel/retryChannel.ts +0 -94
  23. package/src/channel/sandboxChannel.ts +0 -47
  24. package/src/cid/assigner.ts +0 -3
  25. package/src/cid/cachedAssigner.ts +0 -68
  26. package/src/cid/fixedAssigner.ts +0 -13
  27. package/src/cid/index.ts +0 -4
  28. package/src/cid/remoteAssigner.ts +0 -57
  29. package/src/constants.ts +0 -4
  30. package/src/container.ts +0 -410
  31. package/src/contentFetcher.ts +0 -290
  32. package/src/context.ts +0 -139
  33. package/src/error.ts +0 -31
  34. package/src/evaluator.ts +0 -314
  35. package/src/eventManager.ts +0 -53
  36. package/src/eventSubjectProcessor.ts +0 -85
  37. package/src/facade/contentFetcherFacade.ts +0 -69
  38. package/src/facade/evaluatorFacade.ts +0 -111
  39. package/src/facade/index.ts +0 -7
  40. package/src/facade/sdkFacade.ts +0 -310
  41. package/src/facade/sessionFacade.ts +0 -14
  42. package/src/facade/sessionPatch.ts +0 -32
  43. package/src/facade/trackerFacade.ts +0 -98
  44. package/src/facade/userFacade.ts +0 -26
  45. package/src/facade/userPatch.ts +0 -32
  46. package/src/help.ts +0 -24
  47. package/src/index.ts +0 -4
  48. package/src/logging/consoleLogger.ts +0 -38
  49. package/src/logging/filteredLogger.ts +0 -57
  50. package/src/logging/index.ts +0 -5
  51. package/src/logging/logger.ts +0 -13
  52. package/src/logging/namespacedLogger.ts +0 -32
  53. package/src/logging/nullLogger.ts +0 -19
  54. package/src/namespacedStorage.ts +0 -69
  55. package/src/patch.ts +0 -64
  56. package/src/queue/capacityRestrictedQueue.ts +0 -44
  57. package/src/queue/inMemoryQueue.ts +0 -43
  58. package/src/queue/index.ts +0 -5
  59. package/src/queue/monitoredQueue.ts +0 -168
  60. package/src/queue/persistentQueue.ts +0 -73
  61. package/src/queue/queue.ts +0 -15
  62. package/src/retry/arbitraryPolicy.ts +0 -21
  63. package/src/retry/backoffPolicy.ts +0 -84
  64. package/src/retry/index.ts +0 -5
  65. package/src/retry/maxAttemptsPolicy.ts +0 -28
  66. package/src/retry/neverPolicy.ts +0 -11
  67. package/src/retry/policy.ts +0 -5
  68. package/src/schema/attributeSchema.ts +0 -6
  69. package/src/schema/contentFetcherSchemas.ts +0 -23
  70. package/src/schema/contentSchemas.ts +0 -44
  71. package/src/schema/contextSchemas.ts +0 -5
  72. package/src/schema/ecommerceSchemas.ts +0 -179
  73. package/src/schema/evaluatorSchemas.ts +0 -52
  74. package/src/schema/eventSchemas.ts +0 -134
  75. package/src/schema/index.ts +0 -11
  76. package/src/schema/loggerSchema.ts +0 -12
  77. package/src/schema/operationSchemas.ts +0 -102
  78. package/src/schema/sdkFacadeSchemas.ts +0 -64
  79. package/src/schema/sdkSchemas.ts +0 -82
  80. package/src/schema/tokenSchema.ts +0 -42
  81. package/src/schema/userSchema.ts +0 -184
  82. package/src/sdk.ts +0 -183
  83. package/src/sdkEvents.ts +0 -15
  84. package/src/sourceLocation.ts +0 -85
  85. package/src/tab.ts +0 -148
  86. package/src/token/cachedTokenStore.ts +0 -34
  87. package/src/token/inMemoryTokenStore.ts +0 -13
  88. package/src/token/index.ts +0 -4
  89. package/src/token/replicatedTokenStore.ts +0 -21
  90. package/src/token/token.ts +0 -301
  91. package/src/tracker.ts +0 -504
  92. package/src/trackingEvents.ts +0 -452
  93. package/src/transformer.ts +0 -7
  94. package/src/utilityTypes.ts +0 -3
  95. package/src/uuid.ts +0 -43
  96. package/src/validation/arrayType.ts +0 -71
  97. package/src/validation/booleanType.ts +0 -22
  98. package/src/validation/functionType.ts +0 -22
  99. package/src/validation/index.ts +0 -12
  100. package/src/validation/jsonType.ts +0 -156
  101. package/src/validation/mixedSchema.ts +0 -7
  102. package/src/validation/nullType.ts +0 -22
  103. package/src/validation/numberType.ts +0 -59
  104. package/src/validation/objectType.ts +0 -138
  105. package/src/validation/schema.ts +0 -21
  106. package/src/validation/stringType.ts +0 -118
  107. package/src/validation/unionType.ts +0 -53
  108. package/src/validation/violation.ts +0 -23
package/constants.cjs CHANGED
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
  const BASE_ENDPOINT_URL = "https://api.croct.io";
27
27
  const MAX_QUERY_LENGTH = parseInt("<@maxQueryLength@>", 10);
28
- const VERSION = "0.17.10";
28
+ const VERSION = "0.17.11";
29
29
  const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;
30
30
  // Annotate the CommonJS export names for ESM import in node:
31
31
  0 && (module.exports = {
package/constants.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["export const BASE_ENDPOINT_URL = 'https://api.croct.io';\nexport const MAX_QUERY_LENGTH = 500;\nexport const VERSION = '0.17.10';\nexport const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB,SAAS,sBAAsB,EAAE;AAC1D,MAAM,UAAU;AAChB,MAAM,iBAAiB,iBAAiB,OAAO;","names":[]}
1
+ {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["export const BASE_ENDPOINT_URL = 'https://api.croct.io';\nexport const MAX_QUERY_LENGTH = 500;\nexport const VERSION = '0.17.11';\nexport const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB,SAAS,sBAAsB,EAAE;AAC1D,MAAM,UAAU;AAChB,MAAM,iBAAiB,iBAAiB,OAAO;","names":[]}
package/constants.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  declare const BASE_ENDPOINT_URL = "https://api.croct.io";
2
2
  declare const MAX_QUERY_LENGTH: number;
3
- declare const VERSION = "0.17.10";
4
- declare const CLIENT_LIBRARY = "Croct SDK JS v0.17.10";
3
+ declare const VERSION = "0.17.11";
4
+ declare const CLIENT_LIBRARY = "Croct SDK JS v0.17.11";
5
5
 
6
6
  export { BASE_ENDPOINT_URL, CLIENT_LIBRARY, MAX_QUERY_LENGTH, VERSION };
package/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const BASE_ENDPOINT_URL = "https://api.croct.io";
2
2
  const MAX_QUERY_LENGTH = parseInt("<@maxQueryLength@>", 10);
3
- const VERSION = "0.17.10";
3
+ const VERSION = "0.17.11";
4
4
  const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;
5
5
  export {
6
6
  BASE_ENDPOINT_URL,
package/constants.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["src/constants.ts"],"sourcesContent":["export const BASE_ENDPOINT_URL = 'https://api.croct.io';\nexport const MAX_QUERY_LENGTH = 500;\nexport const VERSION = '0.17.10';\nexport const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;\n"],"mappings":"AAAO,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB,SAAS,sBAAsB,EAAE;AAC1D,MAAM,UAAU;AAChB,MAAM,iBAAiB,iBAAiB,OAAO;","names":[]}
1
+ {"version":3,"sources":["src/constants.ts"],"sourcesContent":["export const BASE_ENDPOINT_URL = 'https://api.croct.io';\nexport const MAX_QUERY_LENGTH = 500;\nexport const VERSION = '0.17.11';\nexport const CLIENT_LIBRARY = `Croct SDK JS v${VERSION}`;\n"],"mappings":"AAAO,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB,SAAS,sBAAsB,EAAE;AAC1D,MAAM,UAAU;AAChB,MAAM,iBAAiB,iBAAiB,OAAO;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@croct/sdk",
3
- "version": "0.17.10",
3
+ "version": "0.17.11",
4
4
  "description": "Croct SDK for JavaScript.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -1,150 +0,0 @@
1
- import {JsonStructure, JsonValue} from '@croct/json';
2
- import {Operation, Patch} from './patch';
3
- import {TrackingEvent} from './trackingEvents';
4
- import {
5
- addOperation,
6
- clearOperation,
7
- combineOperation,
8
- decrementOperation,
9
- incrementOperation,
10
- mergeOperation,
11
- setOperation,
12
- unsetOperation,
13
- removeOperation,
14
- } from './schema';
15
-
16
- const operationSchema = {
17
- add: addOperation,
18
- set: setOperation,
19
- merge: mergeOperation,
20
- combine: combineOperation,
21
- increment: incrementOperation,
22
- decrement: decrementOperation,
23
- clear: clearOperation,
24
- unset: unsetOperation,
25
- remove: removeOperation,
26
- };
27
-
28
- export abstract class ActiveRecord<T extends TrackingEvent> {
29
- private readonly operations: Operation[] = [];
30
-
31
- public set(value: JsonValue): this;
32
-
33
- public set(property: string, value: JsonValue): this;
34
-
35
- public set(propertyOrValue: string | JsonValue, value?: JsonValue): this {
36
- if (typeof propertyOrValue === 'string') {
37
- return this.pushOperation({
38
- type: 'set',
39
- path: propertyOrValue,
40
- value: value as JsonValue,
41
- });
42
- }
43
-
44
- return this.pushOperation({
45
- type: 'set',
46
- path: '.',
47
- value: propertyOrValue,
48
- });
49
- }
50
-
51
- public add(property: string, value: JsonValue): this {
52
- return this.pushOperation({
53
- type: 'add',
54
- path: property,
55
- value: value,
56
- });
57
- }
58
-
59
- public combine(property: string, value: JsonValue): this {
60
- return this.pushOperation({
61
- type: 'combine',
62
- path: property,
63
- value: value,
64
- });
65
- }
66
-
67
- public merge(value: JsonStructure): this;
68
-
69
- public merge(property: string, value: JsonStructure): this;
70
-
71
- public merge(propertyOrValue: string | JsonStructure, value?: JsonStructure): this {
72
- if (typeof propertyOrValue === 'string') {
73
- return this.pushOperation({
74
- type: 'merge',
75
- path: propertyOrValue,
76
- value: value as JsonStructure,
77
- });
78
- }
79
-
80
- return this.pushOperation({
81
- type: 'merge',
82
- path: '.',
83
- value: propertyOrValue,
84
- });
85
- }
86
-
87
- public increment(property: string, amount = 1): this {
88
- return this.pushOperation({
89
- type: 'increment',
90
- path: property,
91
- value: amount,
92
- });
93
- }
94
-
95
- public decrement(property: string, amount = 1): this {
96
- return this.pushOperation({
97
- type: 'decrement',
98
- path: property,
99
- value: amount,
100
- });
101
- }
102
-
103
- public clear(property: string): this {
104
- return this.pushOperation({
105
- type: 'clear',
106
- path: property,
107
- });
108
- }
109
-
110
- public unset(property: string): this {
111
- return this.pushOperation({
112
- type: 'unset',
113
- path: property,
114
- });
115
- }
116
-
117
- public remove(property: string, value: JsonValue): this {
118
- return this.pushOperation({
119
- type: 'remove',
120
- path: property,
121
- value: value,
122
- });
123
- }
124
-
125
- private pushOperation(operation: Operation): this {
126
- const {type, ...data} = operation;
127
-
128
- operationSchema[type].validate(data);
129
-
130
- this.operations.push(operation);
131
-
132
- return this;
133
- }
134
-
135
- protected reset(): this {
136
- this.operations.splice(0);
137
-
138
- return this;
139
- }
140
-
141
- public abstract save(): Promise<T>;
142
-
143
- protected isDirty(): boolean {
144
- return this.operations.length > 0;
145
- }
146
-
147
- protected buildPatch(): Patch {
148
- return {operations: this.operations.slice()};
149
- }
150
- }
package/src/apiKey.ts DELETED
@@ -1,208 +0,0 @@
1
- export type ParsedPrivateKey = {
2
- algorithm: string,
3
- encodedKey: string,
4
- };
5
-
6
- type Algorithm = {
7
- keyAlgorithm: EcKeyImportParams,
8
- signatureAlgorithm: EcdsaParams,
9
- };
10
-
11
- export class ApiKey {
12
- private static readonly IDENTIFIER_PATTERN = /^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/i;
13
-
14
- private static readonly PRIVATE_KEY_PATTERN = /^[a-z0-9]+;[^;]+$/i;
15
-
16
- private static readonly ALGORITHMS: Record<string, Algorithm> = {
17
- ES256: {
18
- keyAlgorithm: {
19
- name: 'ECDSA',
20
- namedCurve: 'P-256',
21
- },
22
- signatureAlgorithm: {
23
- name: 'ECDSA',
24
- hash: 'SHA-256',
25
- },
26
- },
27
- };
28
-
29
- private readonly identifier: string;
30
-
31
- private readonly privateKey?: ParsedPrivateKey;
32
-
33
- private importedKey: Promise<CryptoKey>;
34
-
35
- private constructor(identifier: string, privateKey?: ParsedPrivateKey) {
36
- this.identifier = identifier;
37
- this.privateKey = privateKey;
38
- }
39
-
40
- public static from(apiKey: string | ApiKey): ApiKey {
41
- if (apiKey instanceof ApiKey) {
42
- return apiKey;
43
- }
44
-
45
- return ApiKey.parse(apiKey);
46
- }
47
-
48
- public static parse(apiKey: string): ApiKey {
49
- const parts = apiKey.split(':');
50
-
51
- if (parts.length > 2) {
52
- throw new Error('Invalid API key format.');
53
- }
54
-
55
- return ApiKey.of(parts[0], parts[1]);
56
- }
57
-
58
- public static of(identifier: string, privateKey?: string): ApiKey {
59
- if (!ApiKey.IDENTIFIER_PATTERN.test(identifier)) {
60
- throw new Error('The identifier must be a UUID.');
61
- }
62
-
63
- if (privateKey === undefined || privateKey === '') {
64
- return new ApiKey(identifier);
65
- }
66
-
67
- if (!ApiKey.PRIVATE_KEY_PATTERN.test(privateKey)) {
68
- throw new Error('The private key is malformed.');
69
- }
70
-
71
- const [algorithmName, encodedKey] = privateKey.split(';');
72
-
73
- if (!(algorithmName in ApiKey.ALGORITHMS)) {
74
- throw new Error(`Unsupported signing algorithm "${algorithmName}".`);
75
- }
76
-
77
- return new ApiKey(identifier, {
78
- algorithm: algorithmName,
79
- encodedKey: encodedKey,
80
- });
81
- }
82
-
83
- public getIdentifier(): string {
84
- return this.identifier;
85
- }
86
-
87
- public async getIdentifierHash(): Promise<string> {
88
- const identifierBytes = ApiKey.createByteArrayFromHexString(this.identifier.replace(/-/g, ''));
89
- const rawHash = await crypto.subtle.digest('SHA-256', identifierBytes);
90
-
91
- return ApiKey.convertBufferToHexString(rawHash);
92
- }
93
-
94
- public hasPrivateKey(): boolean {
95
- return this.privateKey !== undefined;
96
- }
97
-
98
- public getPrivateKey(): string {
99
- if (this.privateKey === undefined) {
100
- throw new Error('The API key does not have a private key.');
101
- }
102
-
103
- return `${this.privateKey.algorithm};${this.privateKey.encodedKey}`;
104
- }
105
-
106
- public async sign(data: string): Promise<string> {
107
- const key = await this.importKey();
108
- const algorithm = this.getSigningAlgorithm();
109
-
110
- return ApiKey.convertBufferToString(
111
- await crypto.subtle.sign(
112
- ApiKey.ALGORITHMS[algorithm].signatureAlgorithm,
113
- key,
114
- ApiKey.createByteArrayFromString(data),
115
- ),
116
- );
117
- }
118
-
119
- public getSigningAlgorithm(): string {
120
- const {algorithm} = this.getParsedPrivateKey();
121
-
122
- return algorithm;
123
- }
124
-
125
- private importKey(): Promise<CryptoKey> {
126
- const {algorithm, encodedKey} = this.getParsedPrivateKey();
127
-
128
- if (this.importedKey === undefined) {
129
- this.importedKey = crypto.subtle
130
- .importKey(
131
- 'pkcs8',
132
- ApiKey.createByteArrayFromString(atob(encodedKey)),
133
- ApiKey.ALGORITHMS[algorithm].keyAlgorithm,
134
- false,
135
- ['sign'],
136
- );
137
- }
138
-
139
- return this.importedKey;
140
- }
141
-
142
- private getParsedPrivateKey(): ParsedPrivateKey {
143
- if (this.privateKey === undefined) {
144
- throw new Error('The API key does not have a private key.');
145
- }
146
-
147
- return this.privateKey;
148
- }
149
-
150
- public export(): string {
151
- return this.identifier + (this.hasPrivateKey() ? `:${this.getPrivateKey()}` : '');
152
- }
153
-
154
- public toString(): string {
155
- return '[redacted]';
156
- }
157
-
158
- /**
159
- * Create an array buffer from a string.
160
- *
161
- * @see https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
162
- *
163
- * @param data The string to convert.
164
- * @returns The array buffer.
165
- */
166
- private static createByteArrayFromString(data: string): Uint8Array {
167
- const byteArray = new Uint8Array(data.length);
168
-
169
- for (let i = 0; i < byteArray.length; i++) {
170
- byteArray[i] = data.charCodeAt(i);
171
- }
172
-
173
- return byteArray;
174
- }
175
-
176
- private static createByteArrayFromHexString(data: string): Uint8Array {
177
- const byteArray = new Uint8Array(data.length / 2);
178
-
179
- for (let i = 0; i < byteArray.length; i++) {
180
- byteArray[i] = parseInt(data.substring(i * 2, i * 2 + 2), 16);
181
- }
182
-
183
- return byteArray;
184
- }
185
-
186
- /**
187
- * Convert an array buffer to a string.
188
- *
189
- * @see https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
190
- *
191
- * @param buffer The buffer to convert.
192
- * @returns The string.
193
- */
194
- private static convertBufferToString(buffer: ArrayLike<number> | ArrayBufferLike): string {
195
- return String.fromCharCode(...new Uint8Array(buffer));
196
- }
197
-
198
- private static convertBufferToHexString(buffer: ArrayLike<number> | ArrayBufferLike): string {
199
- const bytes = new Uint8Array(buffer);
200
- let hexString = '';
201
-
202
- for (let i = 0; i < bytes.length; i++) {
203
- hexString += bytes[i].toString(16).padStart(2, '0');
204
- }
205
-
206
- return hexString;
207
- }
208
- }
package/src/base64Url.ts DELETED
@@ -1,22 +0,0 @@
1
- function base64Unescape(value: string): string {
2
- return (value + '==='.slice((value.length + 3) % 4)).replace(/-/g, '+').replace(/_/g, '/');
3
- }
4
-
5
- function base64Escape(value: string): string {
6
- return value
7
- .replace(/\+/g, '-')
8
- .replace(/\//g, '_')
9
- .replace(/=/g, '');
10
- }
11
-
12
- export function base64UrlEncode(value: string, utf8 = false): string {
13
- return utf8
14
- ? base64Escape(btoa(String.fromCodePoint(...new TextEncoder().encode(value))))
15
- : base64Escape(btoa(value));
16
- }
17
-
18
- export function base64UrlDecode(value: string, utf8 = false): string {
19
- return utf8
20
- ? new TextDecoder().decode(Uint8Array.from(atob(base64Unescape(value)), m => m.codePointAt(0)!))
21
- : atob(base64Unescape(value));
22
- }
@@ -1,22 +0,0 @@
1
- export interface Cache {
2
- get(): string|null;
3
- put(value: string): void;
4
- clear(): void;
5
- }
6
-
7
- export interface CacheListener {
8
- (value: string|null): void;
9
- }
10
-
11
- export interface ObservableCache extends Cache {
12
- addListener(listener: CacheListener): void;
13
-
14
- removeListener(listener: CacheListener): void;
15
- }
16
-
17
- export namespace ObservableCache {
18
- export function isObservable(cache: Cache): cache is ObservableCache {
19
- return typeof (cache as ObservableCache).addListener === 'function'
20
- && typeof (cache as ObservableCache).removeListener === 'function';
21
- }
22
- }
@@ -1,88 +0,0 @@
1
- import {Cache} from './cache';
2
-
3
- export type CookieCacheConfiguration = {
4
- name: string,
5
- secure?: boolean,
6
- maxAge?: number,
7
- domain?: string,
8
- path?: string,
9
- sameSite?: 'strict' | 'lax' | 'none',
10
- };
11
-
12
- export class CookieCache implements Cache {
13
- private readonly config: CookieCacheConfiguration;
14
-
15
- public constructor(config: CookieCacheConfiguration, defaultSecure = window.location.protocol === 'https:') {
16
- this.config = {
17
- ...config,
18
- path: config.path ?? '/',
19
- };
20
-
21
- if (defaultSecure && this.config.secure === undefined) {
22
- this.config.secure = true;
23
- }
24
-
25
- if (this.config.secure === true && this.config.sameSite === undefined) {
26
- this.config.sameSite = 'none';
27
- }
28
- }
29
-
30
- public get(): string | null {
31
- const entries = document.cookie.split(';');
32
-
33
- for (const entry of entries) {
34
- const [name, value] = entry.split('=');
35
-
36
- if (CookieCache.decode(name).trim() === this.config.name) {
37
- return CookieCache.decode(value.trim());
38
- }
39
- }
40
-
41
- return null;
42
- }
43
-
44
- public put(value: string): void {
45
- document.cookie = CookieCache.serializeCookie(value, this.config);
46
- }
47
-
48
- public clear(): void {
49
- document.cookie = CookieCache.serializeCookie('', {
50
- ...this.config,
51
- maxAge: 0,
52
- });
53
- }
54
-
55
- private static serializeCookie(value: string, config: CookieCacheConfiguration): string {
56
- const cookie = [`${CookieCache.encode(config.name)}=${CookieCache.encode(value)}`];
57
-
58
- if (config.maxAge !== undefined) {
59
- cookie.push(`Max-Age=${config.maxAge}`);
60
- }
61
-
62
- if (config.domain !== undefined) {
63
- cookie.push(`Domain=${CookieCache.encode(config.domain)}`);
64
- }
65
-
66
- if (config.path !== undefined) {
67
- cookie.push(`Path=${CookieCache.encode(config.path)}`);
68
- }
69
-
70
- if (config.secure === true) {
71
- cookie.push('Secure');
72
- }
73
-
74
- if (config.sameSite !== undefined) {
75
- cookie.push(`SameSite=${({strict: 'Strict', lax: 'Lax', none: 'None'})[config.sameSite]}`);
76
- }
77
-
78
- return cookie.join('; ');
79
- }
80
-
81
- private static encode(value: string): string {
82
- return value.replace(/[,; ]+/g, encodeURIComponent);
83
- }
84
-
85
- private static decode(value: string): string {
86
- return decodeURIComponent(value);
87
- }
88
- }
@@ -1,29 +0,0 @@
1
- import {Cache} from './cache';
2
-
3
- export class FallbackCache implements Cache {
4
- private readonly caches: Cache[];
5
-
6
- public constructor(...caches: Cache[]) {
7
- this.caches = caches;
8
- }
9
-
10
- public get(): string|null {
11
- for (const cache of this.caches) {
12
- const value = cache.get();
13
-
14
- if (value !== null) {
15
- return value;
16
- }
17
- }
18
-
19
- return null;
20
- }
21
-
22
- public put(value: string): void {
23
- this.caches.forEach(cache => cache.put(value));
24
- }
25
-
26
- public clear(): void {
27
- this.caches.forEach(cache => cache.clear());
28
- }
29
- }
@@ -1,21 +0,0 @@
1
- import {Cache} from './cache';
2
-
3
- export class InMemoryCache implements Cache {
4
- private cache?: string;
5
-
6
- public constructor(cache?: string) {
7
- this.cache = cache;
8
- }
9
-
10
- public get(): string | null {
11
- return this.cache ?? null;
12
- }
13
-
14
- public put(value: string): void {
15
- this.cache = value;
16
- }
17
-
18
- public clear(): void {
19
- delete this.cache;
20
- }
21
- }
@@ -1,4 +0,0 @@
1
- export * from './cache';
2
- export {FallbackCache} from './fallbackCache';
3
- export {InMemoryCache} from './inMemoryCache';
4
- export {LocalStorageCache} from './localStorageCache';
@@ -1,85 +0,0 @@
1
- import {CacheListener, ObservableCache} from './cache';
2
-
3
- export class LocalStorageCache implements ObservableCache {
4
- private readonly storage: Storage;
5
-
6
- private readonly key: string;
7
-
8
- private value: string|null;
9
-
10
- private readonly listeners: CacheListener[] = [];
11
-
12
- public constructor(storage: Storage, key: string) {
13
- this.storage = storage;
14
- this.key = key;
15
- this.value = storage.getItem(key);
16
- }
17
-
18
- public static autoSync(cache: LocalStorageCache): (() => void) {
19
- const listener = cache.sync.bind(cache);
20
-
21
- window.addEventListener('storage', listener);
22
-
23
- return (): void => window.removeEventListener('storage', listener);
24
- }
25
-
26
- public get(): string|null {
27
- return this.value;
28
- }
29
-
30
- public put(value: string): void {
31
- this.storage.setItem(this.key, value);
32
-
33
- if (this.value !== value) {
34
- this.value = value;
35
- this.notifyChange(value);
36
- }
37
- }
38
-
39
- public clear(): void {
40
- this.storage.removeItem(this.key);
41
-
42
- if (this.value !== null) {
43
- this.value = null;
44
- this.notifyChange(null);
45
- }
46
- }
47
-
48
- public addListener(listener: CacheListener): void {
49
- if (!this.listeners.includes(listener)) {
50
- this.listeners.push(listener);
51
- }
52
- }
53
-
54
- public removeListener(listener: CacheListener): void {
55
- const index = this.listeners.indexOf(listener);
56
-
57
- if (index > -1) {
58
- this.listeners.splice(index, 1);
59
- }
60
- }
61
-
62
- private notifyChange(value: string|null): void {
63
- this.listeners.forEach(listener => listener(value));
64
- }
65
-
66
- private sync(event: StorageEvent): void {
67
- if (event.storageArea !== this.storage || (event.key !== null && event.key !== this.key)) {
68
- // Ignore unrelated changes
69
- return;
70
- }
71
-
72
- /*
73
- * Retrieving the value from the store rather than the event ensures
74
- * the cache will be in sync with the latest value set.
75
- * In case of cascading changes, it prevents notifying listeners
76
- * about intermediate states already outdated at this point.
77
- */
78
- const value = this.storage.getItem(this.key);
79
-
80
- if (this.value !== value) {
81
- this.value = value;
82
- this.notifyChange(value);
83
- }
84
- }
85
- }