@guidelytech/flags 0.7.0 → 0.9.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.
- package/README.md +49 -2
- package/dist/chunk-2RZKAT37.js +1085 -0
- package/dist/chunk-2RZKAT37.js.map +1 -0
- package/dist/chunk-K2HOYVSV.js +1085 -0
- package/dist/chunk-K2HOYVSV.js.map +1 -0
- package/dist/cli.cjs +186 -96
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +121 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -5
- package/dist/index.d.ts +46 -5
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -47,7 +47,7 @@ interface StaticFlagsInput {
|
|
|
47
47
|
declare function createStaticFlags(input?: StaticFlagsInput): FlagsReader;
|
|
48
48
|
|
|
49
49
|
declare const FLAGS_SDK_NAME = "@guidelytech/flags";
|
|
50
|
-
declare const FLAGS_SDK_VERSION = "0.
|
|
50
|
+
declare const FLAGS_SDK_VERSION = "0.9.0";
|
|
51
51
|
declare const DEFAULT_FLAGS_API_URL = "https://guidelytech.com";
|
|
52
52
|
/**
|
|
53
53
|
* - `auto` — fetch at start, then every `pollIntervalSeconds`.
|
|
@@ -56,7 +56,7 @@ declare const DEFAULT_FLAGS_API_URL = "https://guidelytech.com";
|
|
|
56
56
|
* - `stream` — server-sent events push changes; polls while the stream is down.
|
|
57
57
|
*/
|
|
58
58
|
type PollingMode = "auto" | "lazy" | "manual" | "stream";
|
|
59
|
-
/** `localOnly`: never fetch
|
|
59
|
+
/** `localOnly`: never fetch; serve overrides, then the bootstrap. `localOverRemote`: overrides win. `remoteOverLocal`: overrides fill in flags missing remotely. */
|
|
60
60
|
type OverrideBehaviour = "localOnly" | "localOverRemote" | "remoteOverLocal";
|
|
61
61
|
/** Key/value storage for the last payload: `localStorage`-like or AsyncStorage-like (sync or async). */
|
|
62
62
|
interface FlagsStorage {
|
|
@@ -105,6 +105,13 @@ interface FlagsClientOptions {
|
|
|
105
105
|
/** Local flag values (tests, QA, kill switches) applied per `overrideBehaviour`. */
|
|
106
106
|
overrides?: Record<string, JsonValue> | null;
|
|
107
107
|
overrideBehaviour?: OverrideBehaviour;
|
|
108
|
+
/**
|
|
109
|
+
* Read dev overrides from outside the code (default `true`): `GUIDELY_FLAG_OVERRIDES`,
|
|
110
|
+
* `GUIDELY_FLAG_OVERRIDES_FILE` and `GUIDELY_FLAG_OVERRIDE_BEHAVIOUR` environment variables, and
|
|
111
|
+
* the `__GUIDELY_FLAG_OVERRIDES__` / `__GUIDELY_FLAG_OVERRIDE_BEHAVIOUR__` globals (browser tests).
|
|
112
|
+
* They win over `overrides`, and their behaviour over `overrideBehaviour`.
|
|
113
|
+
*/
|
|
114
|
+
devOverrides?: boolean;
|
|
108
115
|
/** Keeps experiment assignments stable (`InMemoryStickyBucketStore`, `LocalStorageStickyBucketStore`). */
|
|
109
116
|
stickyBucketService?: StickyBucketStore;
|
|
110
117
|
/** Persists the last payload. Default: `localStorage` in browsers, none elsewhere. `false` disables. */
|
|
@@ -164,6 +171,7 @@ declare class FlagsClient implements FlagsReader {
|
|
|
164
171
|
private context;
|
|
165
172
|
private attributes;
|
|
166
173
|
private overrides;
|
|
174
|
+
private readonly devOverrides;
|
|
167
175
|
private readonly urlOverrides;
|
|
168
176
|
private offline;
|
|
169
177
|
private destroyed;
|
|
@@ -216,7 +224,7 @@ declare class FlagsClient implements FlagsReader {
|
|
|
216
224
|
setContextAttributes(attributes: Attributes): void;
|
|
217
225
|
/** Context attributes with app attributes merged over them. */
|
|
218
226
|
getAttributes(): Attributes;
|
|
219
|
-
/** Replaces the overrides (`null` clears them). URL overrides stay. */
|
|
227
|
+
/** Replaces the overrides (`null` clears them). Dev and URL overrides stay. */
|
|
220
228
|
setOverrides(overrides: Record<string, JsonValue> | null): void;
|
|
221
229
|
private changeAttributes;
|
|
222
230
|
/** Resolves once the first load settled (bootstrap, network success or failure). Never rejects. */
|
|
@@ -282,6 +290,32 @@ declare class FlagsClient implements FlagsReader {
|
|
|
282
290
|
/** Creates a flags client and starts loading (per `pollingMode`). */
|
|
283
291
|
declare function createFlagsClient(options: FlagsClientOptions): FlagsClient;
|
|
284
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Dev overrides (docs/feature-flags-spec.md §4.1): flag values pinned from outside the code, so CI
|
|
295
|
+
* and tests can switch flags without editing the app. Read once, when a client is created.
|
|
296
|
+
* Runtime-neutral: environment variables via `process.env` (Node, Bun, Next.js server) or
|
|
297
|
+
* `Deno.env`, files via `process.getBuiltinModule("node:fs")` or `Deno`, and a global that test
|
|
298
|
+
* runners set in the page (`page.addInitScript`).
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
declare const OVERRIDES_ENV = "GUIDELY_FLAG_OVERRIDES";
|
|
302
|
+
declare const OVERRIDES_FILE_ENV = "GUIDELY_FLAG_OVERRIDES_FILE";
|
|
303
|
+
declare const OVERRIDE_BEHAVIOUR_ENV = "GUIDELY_FLAG_OVERRIDE_BEHAVIOUR";
|
|
304
|
+
declare const OVERRIDES_GLOBAL = "__GUIDELY_FLAG_OVERRIDES__";
|
|
305
|
+
declare const OVERRIDE_BEHAVIOUR_GLOBAL = "__GUIDELY_FLAG_OVERRIDE_BEHAVIOUR__";
|
|
306
|
+
interface DevOverrides {
|
|
307
|
+
/** Merged values: file, then environment variable, then global (later wins per key). */
|
|
308
|
+
values: Record<string, JsonValue>;
|
|
309
|
+
/** Replaces the configured `overrideBehaviour` when set. */
|
|
310
|
+
behaviour?: OverrideBehaviour;
|
|
311
|
+
/** Where values or the behaviour came from, for the start-up notice. */
|
|
312
|
+
sources: string[];
|
|
313
|
+
/** Unreadable or malformed sources (ignored). */
|
|
314
|
+
errors: string[];
|
|
315
|
+
}
|
|
316
|
+
/** Reads every dev-override source. Never throws: problems land in `errors`. */
|
|
317
|
+
declare function readDevOverrides(): DevOverrides;
|
|
318
|
+
|
|
285
319
|
/** Sticky bucket stores (docs/feature-flags-spec.md §3.5): keep a user's experiment variation across config changes. */
|
|
286
320
|
|
|
287
321
|
/** Keeps assignments in memory for the life of the process (servers, tests). */
|
|
@@ -308,7 +342,14 @@ declare function isEncryptedPayload(x: unknown): x is EncryptedFlagsPayload;
|
|
|
308
342
|
/** A remote-evaluation response (`{ version, flags: { key: EvaluationResult } }`) rather than a payload. */
|
|
309
343
|
declare function isRemoteResults(x: unknown): x is RemoteEvaluationResponse;
|
|
310
344
|
declare function isFlagsPayload(x: unknown): x is FlagsPayload;
|
|
311
|
-
/** `?guidely_flags=key:value,key2:"str"` → overrides
|
|
345
|
+
/** `?guidely_flags=key:value,key2:"str"` → overrides (text as in {@link parseOverrides}; invalid text gives none). */
|
|
312
346
|
declare function parseUrlOverrides(search: string, param?: string): Record<string, JsonValue>;
|
|
347
|
+
/**
|
|
348
|
+
* Overrides text (docs/feature-flags-spec.md §4.1), as held by `GUIDELY_FLAG_OVERRIDES`, an
|
|
349
|
+
* overrides file or `?guidely_flags=`: a JSON object (`{"new-checkout":true}`) or a list
|
|
350
|
+
* `key:value` separated by commas or newlines (`new-checkout:true,limit:5,theme:"dark"`), where each
|
|
351
|
+
* value is JSON when it parses and text otherwise. `null` when the text is a malformed JSON object.
|
|
352
|
+
*/
|
|
353
|
+
declare function parseOverrides(text: string): Record<string, JsonValue> | null;
|
|
313
354
|
|
|
314
|
-
export { Attributes, DEFAULT_FLAGS_API_URL, EncryptedFlagsPayload, EvaluationResult, ExperimentAssignment, FLAGS_SDK_NAME, FLAGS_SDK_VERSION, type FlagDetails, type FlagValue, type FlagsBootstrap, FlagsClient, type FlagsClientOptions, type FlagsEvaluator, type FlagsLogger, FlagsPayload, type FlagsReader, type FlagsStorage, InMemoryStickyBucketStore, JsonValue, LocalStorageStickyBucketStore, type OverrideBehaviour, type PollingMode, RemoteEvaluationResponse, type StaticFlagsInput, StickyAssignments, StickyBucketStore, createFlagsClient, createStaticFlags, isEncryptedPayload, isFlagsPayload, isRemoteResults, parseUrlOverrides, stableStringify };
|
|
355
|
+
export { Attributes, DEFAULT_FLAGS_API_URL, type DevOverrides, EncryptedFlagsPayload, EvaluationResult, ExperimentAssignment, FLAGS_SDK_NAME, FLAGS_SDK_VERSION, type FlagDetails, type FlagValue, type FlagsBootstrap, FlagsClient, type FlagsClientOptions, type FlagsEvaluator, type FlagsLogger, FlagsPayload, type FlagsReader, type FlagsStorage, InMemoryStickyBucketStore, JsonValue, LocalStorageStickyBucketStore, OVERRIDES_ENV, OVERRIDES_FILE_ENV, OVERRIDES_GLOBAL, OVERRIDE_BEHAVIOUR_ENV, OVERRIDE_BEHAVIOUR_GLOBAL, type OverrideBehaviour, type PollingMode, RemoteEvaluationResponse, type StaticFlagsInput, StickyAssignments, StickyBucketStore, createFlagsClient, createStaticFlags, isEncryptedPayload, isFlagsPayload, isRemoteResults, parseOverrides, parseUrlOverrides, readDevOverrides, stableStringify };
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ interface StaticFlagsInput {
|
|
|
47
47
|
declare function createStaticFlags(input?: StaticFlagsInput): FlagsReader;
|
|
48
48
|
|
|
49
49
|
declare const FLAGS_SDK_NAME = "@guidelytech/flags";
|
|
50
|
-
declare const FLAGS_SDK_VERSION = "0.
|
|
50
|
+
declare const FLAGS_SDK_VERSION = "0.9.0";
|
|
51
51
|
declare const DEFAULT_FLAGS_API_URL = "https://guidelytech.com";
|
|
52
52
|
/**
|
|
53
53
|
* - `auto` — fetch at start, then every `pollIntervalSeconds`.
|
|
@@ -56,7 +56,7 @@ declare const DEFAULT_FLAGS_API_URL = "https://guidelytech.com";
|
|
|
56
56
|
* - `stream` — server-sent events push changes; polls while the stream is down.
|
|
57
57
|
*/
|
|
58
58
|
type PollingMode = "auto" | "lazy" | "manual" | "stream";
|
|
59
|
-
/** `localOnly`: never fetch
|
|
59
|
+
/** `localOnly`: never fetch; serve overrides, then the bootstrap. `localOverRemote`: overrides win. `remoteOverLocal`: overrides fill in flags missing remotely. */
|
|
60
60
|
type OverrideBehaviour = "localOnly" | "localOverRemote" | "remoteOverLocal";
|
|
61
61
|
/** Key/value storage for the last payload: `localStorage`-like or AsyncStorage-like (sync or async). */
|
|
62
62
|
interface FlagsStorage {
|
|
@@ -105,6 +105,13 @@ interface FlagsClientOptions {
|
|
|
105
105
|
/** Local flag values (tests, QA, kill switches) applied per `overrideBehaviour`. */
|
|
106
106
|
overrides?: Record<string, JsonValue> | null;
|
|
107
107
|
overrideBehaviour?: OverrideBehaviour;
|
|
108
|
+
/**
|
|
109
|
+
* Read dev overrides from outside the code (default `true`): `GUIDELY_FLAG_OVERRIDES`,
|
|
110
|
+
* `GUIDELY_FLAG_OVERRIDES_FILE` and `GUIDELY_FLAG_OVERRIDE_BEHAVIOUR` environment variables, and
|
|
111
|
+
* the `__GUIDELY_FLAG_OVERRIDES__` / `__GUIDELY_FLAG_OVERRIDE_BEHAVIOUR__` globals (browser tests).
|
|
112
|
+
* They win over `overrides`, and their behaviour over `overrideBehaviour`.
|
|
113
|
+
*/
|
|
114
|
+
devOverrides?: boolean;
|
|
108
115
|
/** Keeps experiment assignments stable (`InMemoryStickyBucketStore`, `LocalStorageStickyBucketStore`). */
|
|
109
116
|
stickyBucketService?: StickyBucketStore;
|
|
110
117
|
/** Persists the last payload. Default: `localStorage` in browsers, none elsewhere. `false` disables. */
|
|
@@ -164,6 +171,7 @@ declare class FlagsClient implements FlagsReader {
|
|
|
164
171
|
private context;
|
|
165
172
|
private attributes;
|
|
166
173
|
private overrides;
|
|
174
|
+
private readonly devOverrides;
|
|
167
175
|
private readonly urlOverrides;
|
|
168
176
|
private offline;
|
|
169
177
|
private destroyed;
|
|
@@ -216,7 +224,7 @@ declare class FlagsClient implements FlagsReader {
|
|
|
216
224
|
setContextAttributes(attributes: Attributes): void;
|
|
217
225
|
/** Context attributes with app attributes merged over them. */
|
|
218
226
|
getAttributes(): Attributes;
|
|
219
|
-
/** Replaces the overrides (`null` clears them). URL overrides stay. */
|
|
227
|
+
/** Replaces the overrides (`null` clears them). Dev and URL overrides stay. */
|
|
220
228
|
setOverrides(overrides: Record<string, JsonValue> | null): void;
|
|
221
229
|
private changeAttributes;
|
|
222
230
|
/** Resolves once the first load settled (bootstrap, network success or failure). Never rejects. */
|
|
@@ -282,6 +290,32 @@ declare class FlagsClient implements FlagsReader {
|
|
|
282
290
|
/** Creates a flags client and starts loading (per `pollingMode`). */
|
|
283
291
|
declare function createFlagsClient(options: FlagsClientOptions): FlagsClient;
|
|
284
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Dev overrides (docs/feature-flags-spec.md §4.1): flag values pinned from outside the code, so CI
|
|
295
|
+
* and tests can switch flags without editing the app. Read once, when a client is created.
|
|
296
|
+
* Runtime-neutral: environment variables via `process.env` (Node, Bun, Next.js server) or
|
|
297
|
+
* `Deno.env`, files via `process.getBuiltinModule("node:fs")` or `Deno`, and a global that test
|
|
298
|
+
* runners set in the page (`page.addInitScript`).
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
declare const OVERRIDES_ENV = "GUIDELY_FLAG_OVERRIDES";
|
|
302
|
+
declare const OVERRIDES_FILE_ENV = "GUIDELY_FLAG_OVERRIDES_FILE";
|
|
303
|
+
declare const OVERRIDE_BEHAVIOUR_ENV = "GUIDELY_FLAG_OVERRIDE_BEHAVIOUR";
|
|
304
|
+
declare const OVERRIDES_GLOBAL = "__GUIDELY_FLAG_OVERRIDES__";
|
|
305
|
+
declare const OVERRIDE_BEHAVIOUR_GLOBAL = "__GUIDELY_FLAG_OVERRIDE_BEHAVIOUR__";
|
|
306
|
+
interface DevOverrides {
|
|
307
|
+
/** Merged values: file, then environment variable, then global (later wins per key). */
|
|
308
|
+
values: Record<string, JsonValue>;
|
|
309
|
+
/** Replaces the configured `overrideBehaviour` when set. */
|
|
310
|
+
behaviour?: OverrideBehaviour;
|
|
311
|
+
/** Where values or the behaviour came from, for the start-up notice. */
|
|
312
|
+
sources: string[];
|
|
313
|
+
/** Unreadable or malformed sources (ignored). */
|
|
314
|
+
errors: string[];
|
|
315
|
+
}
|
|
316
|
+
/** Reads every dev-override source. Never throws: problems land in `errors`. */
|
|
317
|
+
declare function readDevOverrides(): DevOverrides;
|
|
318
|
+
|
|
285
319
|
/** Sticky bucket stores (docs/feature-flags-spec.md §3.5): keep a user's experiment variation across config changes. */
|
|
286
320
|
|
|
287
321
|
/** Keeps assignments in memory for the life of the process (servers, tests). */
|
|
@@ -308,7 +342,14 @@ declare function isEncryptedPayload(x: unknown): x is EncryptedFlagsPayload;
|
|
|
308
342
|
/** A remote-evaluation response (`{ version, flags: { key: EvaluationResult } }`) rather than a payload. */
|
|
309
343
|
declare function isRemoteResults(x: unknown): x is RemoteEvaluationResponse;
|
|
310
344
|
declare function isFlagsPayload(x: unknown): x is FlagsPayload;
|
|
311
|
-
/** `?guidely_flags=key:value,key2:"str"` → overrides
|
|
345
|
+
/** `?guidely_flags=key:value,key2:"str"` → overrides (text as in {@link parseOverrides}; invalid text gives none). */
|
|
312
346
|
declare function parseUrlOverrides(search: string, param?: string): Record<string, JsonValue>;
|
|
347
|
+
/**
|
|
348
|
+
* Overrides text (docs/feature-flags-spec.md §4.1), as held by `GUIDELY_FLAG_OVERRIDES`, an
|
|
349
|
+
* overrides file or `?guidely_flags=`: a JSON object (`{"new-checkout":true}`) or a list
|
|
350
|
+
* `key:value` separated by commas or newlines (`new-checkout:true,limit:5,theme:"dark"`), where each
|
|
351
|
+
* value is JSON when it parses and text otherwise. `null` when the text is a malformed JSON object.
|
|
352
|
+
*/
|
|
353
|
+
declare function parseOverrides(text: string): Record<string, JsonValue> | null;
|
|
313
354
|
|
|
314
|
-
export { Attributes, DEFAULT_FLAGS_API_URL, EncryptedFlagsPayload, EvaluationResult, ExperimentAssignment, FLAGS_SDK_NAME, FLAGS_SDK_VERSION, type FlagDetails, type FlagValue, type FlagsBootstrap, FlagsClient, type FlagsClientOptions, type FlagsEvaluator, type FlagsLogger, FlagsPayload, type FlagsReader, type FlagsStorage, InMemoryStickyBucketStore, JsonValue, LocalStorageStickyBucketStore, type OverrideBehaviour, type PollingMode, RemoteEvaluationResponse, type StaticFlagsInput, StickyAssignments, StickyBucketStore, createFlagsClient, createStaticFlags, isEncryptedPayload, isFlagsPayload, isRemoteResults, parseUrlOverrides, stableStringify };
|
|
355
|
+
export { Attributes, DEFAULT_FLAGS_API_URL, type DevOverrides, EncryptedFlagsPayload, EvaluationResult, ExperimentAssignment, FLAGS_SDK_NAME, FLAGS_SDK_VERSION, type FlagDetails, type FlagValue, type FlagsBootstrap, FlagsClient, type FlagsClientOptions, type FlagsEvaluator, type FlagsLogger, FlagsPayload, type FlagsReader, type FlagsStorage, InMemoryStickyBucketStore, JsonValue, LocalStorageStickyBucketStore, OVERRIDES_ENV, OVERRIDES_FILE_ENV, OVERRIDES_GLOBAL, OVERRIDE_BEHAVIOUR_ENV, OVERRIDE_BEHAVIOUR_GLOBAL, type OverrideBehaviour, type PollingMode, RemoteEvaluationResponse, type StaticFlagsInput, StickyAssignments, StickyBucketStore, createFlagsClient, createStaticFlags, isEncryptedPayload, isFlagsPayload, isRemoteResults, parseOverrides, parseUrlOverrides, readDevOverrides, stableStringify };
|
package/dist/index.js
CHANGED
|
@@ -3,14 +3,21 @@ import {
|
|
|
3
3
|
FLAGS_SDK_NAME,
|
|
4
4
|
FLAGS_SDK_VERSION,
|
|
5
5
|
FlagsClient,
|
|
6
|
+
OVERRIDES_ENV,
|
|
7
|
+
OVERRIDES_FILE_ENV,
|
|
8
|
+
OVERRIDES_GLOBAL,
|
|
9
|
+
OVERRIDE_BEHAVIOUR_ENV,
|
|
10
|
+
OVERRIDE_BEHAVIOUR_GLOBAL,
|
|
6
11
|
createFlagsClient,
|
|
7
12
|
createStaticFlags,
|
|
8
13
|
isEncryptedPayload,
|
|
9
14
|
isFlagsPayload,
|
|
10
15
|
isRemoteResults,
|
|
16
|
+
parseOverrides,
|
|
11
17
|
parseUrlOverrides,
|
|
18
|
+
readDevOverrides,
|
|
12
19
|
stableStringify
|
|
13
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-K2HOYVSV.js";
|
|
14
21
|
import {
|
|
15
22
|
ARRAY_OPERATORS,
|
|
16
23
|
ATTRIBUTE_OPERATORS,
|
|
@@ -94,6 +101,11 @@ export {
|
|
|
94
101
|
InMemoryStickyBucketStore,
|
|
95
102
|
LocalStorageStickyBucketStore,
|
|
96
103
|
NUMBER_OPERATORS,
|
|
104
|
+
OVERRIDES_ENV,
|
|
105
|
+
OVERRIDES_FILE_ENV,
|
|
106
|
+
OVERRIDES_GLOBAL,
|
|
107
|
+
OVERRIDE_BEHAVIOUR_ENV,
|
|
108
|
+
OVERRIDE_BEHAVIOUR_GLOBAL,
|
|
97
109
|
PRESENCE_OPERATORS,
|
|
98
110
|
SEMVER_OPERATORS,
|
|
99
111
|
TEXT_OPERATORS,
|
|
@@ -116,8 +128,10 @@ export {
|
|
|
116
128
|
jsonEquals,
|
|
117
129
|
lookupAttribute,
|
|
118
130
|
numberOf,
|
|
131
|
+
parseOverrides,
|
|
119
132
|
parseSemver,
|
|
120
133
|
parseUrlOverrides,
|
|
134
|
+
readDevOverrides,
|
|
121
135
|
sha256Hex,
|
|
122
136
|
stableStringify,
|
|
123
137
|
textOf
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sticky.ts"],"sourcesContent":["/** Sticky bucket stores (docs/feature-flags-spec.md §3.5): keep a user's experiment variation across config changes. */\nimport type { StickyAssignments, StickyBucketStore } from \"./types\";\n\n/** Keeps assignments in memory for the life of the process (servers, tests). */\nexport class InMemoryStickyBucketStore implements StickyBucketStore {\n private readonly docs = new Map<string, StickyAssignments>();\n get(docKey: string): StickyAssignments | null {\n return this.docs.get(docKey) ?? null;\n }\n set(docKey: string, assignments: StickyAssignments): void {\n this.docs.set(docKey, { ...assignments });\n }\n}\n\n/** Persists assignments in `localStorage` (browsers). Falls back to memory when storage is unavailable. */\nexport class LocalStorageStickyBucketStore implements StickyBucketStore {\n private readonly memory = new InMemoryStickyBucketStore();\n constructor(private readonly prefix = \"guidely:sticky:\") {}\n\n private get storage(): Storage | null {\n try {\n return typeof localStorage !== \"undefined\" ? localStorage : null;\n } catch {\n return null;\n }\n }\n\n get(docKey: string): StickyAssignments | null {\n try {\n const raw = this.storage?.getItem(this.prefix + docKey);\n if (raw) return JSON.parse(raw) as StickyAssignments;\n } catch {\n /* private mode, corrupt entry */\n }\n return this.memory.get(docKey);\n }\n\n set(docKey: string, assignments: StickyAssignments): void {\n this.memory.set(docKey, assignments);\n try {\n this.storage?.setItem(this.prefix + docKey, JSON.stringify(assignments));\n } catch {\n /* quota / private mode */\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/sticky.ts"],"sourcesContent":["/** Sticky bucket stores (docs/feature-flags-spec.md §3.5): keep a user's experiment variation across config changes. */\nimport type { StickyAssignments, StickyBucketStore } from \"./types\";\n\n/** Keeps assignments in memory for the life of the process (servers, tests). */\nexport class InMemoryStickyBucketStore implements StickyBucketStore {\n private readonly docs = new Map<string, StickyAssignments>();\n get(docKey: string): StickyAssignments | null {\n return this.docs.get(docKey) ?? null;\n }\n set(docKey: string, assignments: StickyAssignments): void {\n this.docs.set(docKey, { ...assignments });\n }\n}\n\n/** Persists assignments in `localStorage` (browsers). Falls back to memory when storage is unavailable. */\nexport class LocalStorageStickyBucketStore implements StickyBucketStore {\n private readonly memory = new InMemoryStickyBucketStore();\n constructor(private readonly prefix = \"guidely:sticky:\") {}\n\n private get storage(): Storage | null {\n try {\n return typeof localStorage !== \"undefined\" ? localStorage : null;\n } catch {\n return null;\n }\n }\n\n get(docKey: string): StickyAssignments | null {\n try {\n const raw = this.storage?.getItem(this.prefix + docKey);\n if (raw) return JSON.parse(raw) as StickyAssignments;\n } catch {\n /* private mode, corrupt entry */\n }\n return this.memory.get(docKey);\n }\n\n set(docKey: string, assignments: StickyAssignments): void {\n this.memory.set(docKey, assignments);\n try {\n this.storage?.setItem(this.prefix + docKey, JSON.stringify(assignments));\n } catch {\n /* quota / private mode */\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIO,IAAM,4BAAN,MAA6D;AAAA,EAA7D;AACL,wBAAiB,QAAO,oBAAI,IAA+B;AAAA;AAAA,EAC3D,IAAI,QAA0C;AAC5C,WAAO,KAAK,KAAK,IAAI,MAAM,KAAK;AAAA,EAClC;AAAA,EACA,IAAI,QAAgB,aAAsC;AACxD,SAAK,KAAK,IAAI,QAAQ,EAAE,GAAG,YAAY,CAAC;AAAA,EAC1C;AACF;AAGO,IAAM,gCAAN,MAAiE;AAAA,EAEtE,YAA6B,SAAS,mBAAmB;AAA5B;AAD7B,wBAAiB,UAAS,IAAI,0BAA0B;AAAA,EACE;AAAA,EAE1D,IAAY,UAA0B;AACpC,QAAI;AACF,aAAO,OAAO,iBAAiB,cAAc,eAAe;AAAA,IAC9D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAI,QAA0C;AAC5C,QAAI;AACF,YAAM,MAAM,KAAK,SAAS,QAAQ,KAAK,SAAS,MAAM;AACtD,UAAI,IAAK,QAAO,KAAK,MAAM,GAAG;AAAA,IAChC,QAAQ;AAAA,IAER;AACA,WAAO,KAAK,OAAO,IAAI,MAAM;AAAA,EAC/B;AAAA,EAEA,IAAI,QAAgB,aAAsC;AACxD,SAAK,OAAO,IAAI,QAAQ,WAAW;AACnC,QAAI;AACF,WAAK,SAAS,QAAQ,KAAK,SAAS,QAAQ,KAAK,UAAU,WAAW,CAAC;AAAA,IACzE,QAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guidelytech/flags",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Guidely feature flags and experiments for TypeScript: browsers, Node.js, Next.js, edge runtimes",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
},
|
|
43
43
|
"repository": {
|
|
44
44
|
"type": "git",
|
|
45
|
-
"url": "git+https://github.com/
|
|
45
|
+
"url": "git+https://github.com/GuidelyTech/Guidely.git",
|
|
46
46
|
"directory": "packages/flags"
|
|
47
47
|
},
|
|
48
|
-
"homepage": "https://github.com/
|
|
48
|
+
"homepage": "https://github.com/GuidelyTech/Guidely/tree/main/packages/flags#readme",
|
|
49
49
|
"bugs": {
|
|
50
|
-
"url": "https://github.com/
|
|
50
|
+
"url": "https://github.com/GuidelyTech/Guidely/issues"
|
|
51
51
|
},
|
|
52
52
|
"keywords": [
|
|
53
53
|
"guidely",
|