@augmenting-integrations/flags 0.1.0 → 0.2.2
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/dist/{index.mjs → index.cjs} +32 -5
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +83 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/createFlags.jsx +0 -95
- package/dist/createFlags.jsx.map +0 -1
- package/dist/index.mjs.map +0 -1
|
@@ -1,5 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createFlags: () => createFlags
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
1
27
|
// src/createFlags.tsx
|
|
2
|
-
|
|
28
|
+
var import_react = require("react");
|
|
3
29
|
var EMPTY = Object.freeze({});
|
|
4
30
|
function createFlags(opts) {
|
|
5
31
|
const { flags, storageKey } = opts;
|
|
@@ -52,7 +78,7 @@ function createFlags(opts) {
|
|
|
52
78
|
return EMPTY;
|
|
53
79
|
}
|
|
54
80
|
function useFlag(key) {
|
|
55
|
-
const overrides = useSyncExternalStore(subscribe, readSnapshot, getServerSnapshot);
|
|
81
|
+
const overrides = (0, import_react.useSyncExternalStore)(subscribe, readSnapshot, getServerSnapshot);
|
|
56
82
|
if (key in overrides) return overrides[key];
|
|
57
83
|
const def = flags[key];
|
|
58
84
|
return def.default;
|
|
@@ -78,7 +104,8 @@ function createFlags(opts) {
|
|
|
78
104
|
}
|
|
79
105
|
return { useFlag, setFlag, resetFlag, resetAllFlags, listFlags };
|
|
80
106
|
}
|
|
81
|
-
export
|
|
107
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
108
|
+
0 && (module.exports = {
|
|
82
109
|
createFlags
|
|
83
|
-
};
|
|
84
|
-
//# sourceMappingURL=index.
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/createFlags.tsx"],"sourcesContent":["export type FlagDef =\n | { type: \"boolean\"; default: boolean; description: string }\n | { type: \"string\"; default: string; description: string }\n | { type: \"number\"; default: number; description: string }\n | {\n type: \"enum\";\n default: string;\n options: string[];\n description: string;\n };\n\nexport type FlagsMap = Record<string, FlagDef>;\n\nexport { createFlags } from \"./createFlags.js\";\n","\"use client\";\n\nimport { useSyncExternalStore } from \"react\";\nimport type { FlagDef, FlagsMap } from \"./index.js\";\n\ntype Overrides = Record<string, unknown>;\n\nconst EMPTY: Overrides = Object.freeze({}) as Overrides;\n\n/**\n * Build a per-app flag system. Each consuming app calls this once with its\n * own flag definitions and a unique localStorage namespace. Returns a hook\n * + helpers + a studio panel scoped to those flags.\n */\nexport function createFlags<F extends FlagsMap>(opts: { flags: F; storageKey: string }) {\n const { flags, storageKey } = opts;\n const eventName = `flags:changed:${storageKey}`;\n\n // Cache for stable getSnapshot reference (required by useSyncExternalStore).\n let cachedRaw: string | null | undefined = undefined;\n let cachedSnapshot: Overrides = {};\n\n function readSnapshot(): Overrides {\n if (typeof window === \"undefined\") return EMPTY;\n let raw: string | null;\n try {\n raw = window.localStorage.getItem(storageKey);\n } catch {\n return cachedSnapshot;\n }\n if (raw === cachedRaw) return cachedSnapshot;\n cachedRaw = raw;\n try {\n cachedSnapshot = raw ? (JSON.parse(raw) as Overrides) : {};\n } catch {\n cachedSnapshot = {};\n }\n return cachedSnapshot;\n }\n\n function writeOverrides(next: Overrides) {\n if (typeof window === \"undefined\") return;\n const json = JSON.stringify(next);\n try {\n window.localStorage.setItem(storageKey, json);\n } catch {\n // ignore quota / private mode errors\n }\n cachedRaw = json;\n cachedSnapshot = next;\n window.dispatchEvent(new Event(eventName));\n }\n\n function subscribe(callback: () => void) {\n if (typeof window === \"undefined\") return () => {};\n const handler = () => {\n cachedRaw = undefined;\n callback();\n };\n window.addEventListener(eventName, handler);\n window.addEventListener(\"storage\", handler);\n return () => {\n window.removeEventListener(eventName, handler);\n window.removeEventListener(\"storage\", handler);\n };\n }\n\n function getServerSnapshot(): Overrides {\n return EMPTY;\n }\n\n type FlagKey = keyof F & string;\n\n function useFlag<T = unknown>(key: FlagKey): T {\n const overrides = useSyncExternalStore(subscribe, readSnapshot, getServerSnapshot);\n if (key in overrides) return overrides[key] as T;\n const def = flags[key] as FlagDef;\n return def.default as T;\n }\n\n function setFlag(key: FlagKey, value: unknown) {\n const current = typeof window === \"undefined\" ? {} : { ...readSnapshot() };\n current[key] = value;\n writeOverrides(current);\n }\n\n function resetFlag(key: FlagKey) {\n const current = typeof window === \"undefined\" ? {} : { ...readSnapshot() };\n delete current[key];\n writeOverrides(current);\n }\n\n function resetAllFlags() {\n writeOverrides({});\n }\n\n function listFlags() {\n return Object.entries(flags).map(([key, def]) => ({\n key,\n ...(def as FlagDef),\n }));\n }\n\n return { useFlag, setFlag, resetFlag, resetAllFlags, listFlags };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,mBAAqC;AAKrC,IAAM,QAAmB,OAAO,OAAO,CAAC,CAAC;AAOlC,SAAS,YAAgC,MAAwC;AACtF,QAAM,EAAE,OAAO,WAAW,IAAI;AAC9B,QAAM,YAAY,iBAAiB,UAAU;AAG7C,MAAI,YAAuC;AAC3C,MAAI,iBAA4B,CAAC;AAEjC,WAAS,eAA0B;AACjC,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAI;AACJ,QAAI;AACF,YAAM,OAAO,aAAa,QAAQ,UAAU;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,UAAW,QAAO;AAC9B,gBAAY;AACZ,QAAI;AACF,uBAAiB,MAAO,KAAK,MAAM,GAAG,IAAkB,CAAC;AAAA,IAC3D,QAAQ;AACN,uBAAiB,CAAC;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAEA,WAAS,eAAe,MAAiB;AACvC,QAAI,OAAO,WAAW,YAAa;AACnC,UAAM,OAAO,KAAK,UAAU,IAAI;AAChC,QAAI;AACF,aAAO,aAAa,QAAQ,YAAY,IAAI;AAAA,IAC9C,QAAQ;AAAA,IAER;AACA,gBAAY;AACZ,qBAAiB;AACjB,WAAO,cAAc,IAAI,MAAM,SAAS,CAAC;AAAA,EAC3C;AAEA,WAAS,UAAU,UAAsB;AACvC,QAAI,OAAO,WAAW,YAAa,QAAO,MAAM;AAAA,IAAC;AACjD,UAAM,UAAU,MAAM;AACpB,kBAAY;AACZ,eAAS;AAAA,IACX;AACA,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,MAAM;AACX,aAAO,oBAAoB,WAAW,OAAO;AAC7C,aAAO,oBAAoB,WAAW,OAAO;AAAA,IAC/C;AAAA,EACF;AAEA,WAAS,oBAA+B;AACtC,WAAO;AAAA,EACT;AAIA,WAAS,QAAqB,KAAiB;AAC7C,UAAM,gBAAY,mCAAqB,WAAW,cAAc,iBAAiB;AACjF,QAAI,OAAO,UAAW,QAAO,UAAU,GAAG;AAC1C,UAAM,MAAM,MAAM,GAAG;AACrB,WAAO,IAAI;AAAA,EACb;AAEA,WAAS,QAAQ,KAAc,OAAgB;AAC7C,UAAM,UAAU,OAAO,WAAW,cAAc,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE;AACzE,YAAQ,GAAG,IAAI;AACf,mBAAe,OAAO;AAAA,EACxB;AAEA,WAAS,UAAU,KAAc;AAC/B,UAAM,UAAU,OAAO,WAAW,cAAc,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE;AACzE,WAAO,QAAQ,GAAG;AAClB,mBAAe,OAAO;AAAA,EACxB;AAEA,WAAS,gBAAgB;AACvB,mBAAe,CAAC,CAAC;AAAA,EACnB;AAEA,WAAS,YAAY;AACnB,WAAO,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO;AAAA,MAChD;AAAA,MACA,GAAI;AAAA,IACN,EAAE;AAAA,EACJ;AAEA,SAAO,EAAE,SAAS,SAAS,WAAW,eAAe,UAAU;AACjE;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,84 @@
|
|
|
1
|
-
|
|
1
|
+
// src/createFlags.tsx
|
|
2
|
+
import { useSyncExternalStore } from "react";
|
|
3
|
+
var EMPTY = Object.freeze({});
|
|
4
|
+
function createFlags(opts) {
|
|
5
|
+
const { flags, storageKey } = opts;
|
|
6
|
+
const eventName = `flags:changed:${storageKey}`;
|
|
7
|
+
let cachedRaw = void 0;
|
|
8
|
+
let cachedSnapshot = {};
|
|
9
|
+
function readSnapshot() {
|
|
10
|
+
if (typeof window === "undefined") return EMPTY;
|
|
11
|
+
let raw;
|
|
12
|
+
try {
|
|
13
|
+
raw = window.localStorage.getItem(storageKey);
|
|
14
|
+
} catch {
|
|
15
|
+
return cachedSnapshot;
|
|
16
|
+
}
|
|
17
|
+
if (raw === cachedRaw) return cachedSnapshot;
|
|
18
|
+
cachedRaw = raw;
|
|
19
|
+
try {
|
|
20
|
+
cachedSnapshot = raw ? JSON.parse(raw) : {};
|
|
21
|
+
} catch {
|
|
22
|
+
cachedSnapshot = {};
|
|
23
|
+
}
|
|
24
|
+
return cachedSnapshot;
|
|
25
|
+
}
|
|
26
|
+
function writeOverrides(next) {
|
|
27
|
+
if (typeof window === "undefined") return;
|
|
28
|
+
const json = JSON.stringify(next);
|
|
29
|
+
try {
|
|
30
|
+
window.localStorage.setItem(storageKey, json);
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
cachedRaw = json;
|
|
34
|
+
cachedSnapshot = next;
|
|
35
|
+
window.dispatchEvent(new Event(eventName));
|
|
36
|
+
}
|
|
37
|
+
function subscribe(callback) {
|
|
38
|
+
if (typeof window === "undefined") return () => {
|
|
39
|
+
};
|
|
40
|
+
const handler = () => {
|
|
41
|
+
cachedRaw = void 0;
|
|
42
|
+
callback();
|
|
43
|
+
};
|
|
44
|
+
window.addEventListener(eventName, handler);
|
|
45
|
+
window.addEventListener("storage", handler);
|
|
46
|
+
return () => {
|
|
47
|
+
window.removeEventListener(eventName, handler);
|
|
48
|
+
window.removeEventListener("storage", handler);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function getServerSnapshot() {
|
|
52
|
+
return EMPTY;
|
|
53
|
+
}
|
|
54
|
+
function useFlag(key) {
|
|
55
|
+
const overrides = useSyncExternalStore(subscribe, readSnapshot, getServerSnapshot);
|
|
56
|
+
if (key in overrides) return overrides[key];
|
|
57
|
+
const def = flags[key];
|
|
58
|
+
return def.default;
|
|
59
|
+
}
|
|
60
|
+
function setFlag(key, value) {
|
|
61
|
+
const current = typeof window === "undefined" ? {} : { ...readSnapshot() };
|
|
62
|
+
current[key] = value;
|
|
63
|
+
writeOverrides(current);
|
|
64
|
+
}
|
|
65
|
+
function resetFlag(key) {
|
|
66
|
+
const current = typeof window === "undefined" ? {} : { ...readSnapshot() };
|
|
67
|
+
delete current[key];
|
|
68
|
+
writeOverrides(current);
|
|
69
|
+
}
|
|
70
|
+
function resetAllFlags() {
|
|
71
|
+
writeOverrides({});
|
|
72
|
+
}
|
|
73
|
+
function listFlags() {
|
|
74
|
+
return Object.entries(flags).map(([key, def]) => ({
|
|
75
|
+
key,
|
|
76
|
+
...def
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
return { useFlag, setFlag, resetFlag, resetAllFlags, listFlags };
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
createFlags
|
|
83
|
+
};
|
|
2
84
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"sources":["../src/createFlags.tsx"],"sourcesContent":["\"use client\";\n\nimport { useSyncExternalStore } from \"react\";\nimport type { FlagDef, FlagsMap } from \"./index.js\";\n\ntype Overrides = Record<string, unknown>;\n\nconst EMPTY: Overrides = Object.freeze({}) as Overrides;\n\n/**\n * Build a per-app flag system. Each consuming app calls this once with its\n * own flag definitions and a unique localStorage namespace. Returns a hook\n * + helpers + a studio panel scoped to those flags.\n */\nexport function createFlags<F extends FlagsMap>(opts: { flags: F; storageKey: string }) {\n const { flags, storageKey } = opts;\n const eventName = `flags:changed:${storageKey}`;\n\n // Cache for stable getSnapshot reference (required by useSyncExternalStore).\n let cachedRaw: string | null | undefined = undefined;\n let cachedSnapshot: Overrides = {};\n\n function readSnapshot(): Overrides {\n if (typeof window === \"undefined\") return EMPTY;\n let raw: string | null;\n try {\n raw = window.localStorage.getItem(storageKey);\n } catch {\n return cachedSnapshot;\n }\n if (raw === cachedRaw) return cachedSnapshot;\n cachedRaw = raw;\n try {\n cachedSnapshot = raw ? (JSON.parse(raw) as Overrides) : {};\n } catch {\n cachedSnapshot = {};\n }\n return cachedSnapshot;\n }\n\n function writeOverrides(next: Overrides) {\n if (typeof window === \"undefined\") return;\n const json = JSON.stringify(next);\n try {\n window.localStorage.setItem(storageKey, json);\n } catch {\n // ignore quota / private mode errors\n }\n cachedRaw = json;\n cachedSnapshot = next;\n window.dispatchEvent(new Event(eventName));\n }\n\n function subscribe(callback: () => void) {\n if (typeof window === \"undefined\") return () => {};\n const handler = () => {\n cachedRaw = undefined;\n callback();\n };\n window.addEventListener(eventName, handler);\n window.addEventListener(\"storage\", handler);\n return () => {\n window.removeEventListener(eventName, handler);\n window.removeEventListener(\"storage\", handler);\n };\n }\n\n function getServerSnapshot(): Overrides {\n return EMPTY;\n }\n\n type FlagKey = keyof F & string;\n\n function useFlag<T = unknown>(key: FlagKey): T {\n const overrides = useSyncExternalStore(subscribe, readSnapshot, getServerSnapshot);\n if (key in overrides) return overrides[key] as T;\n const def = flags[key] as FlagDef;\n return def.default as T;\n }\n\n function setFlag(key: FlagKey, value: unknown) {\n const current = typeof window === \"undefined\" ? {} : { ...readSnapshot() };\n current[key] = value;\n writeOverrides(current);\n }\n\n function resetFlag(key: FlagKey) {\n const current = typeof window === \"undefined\" ? {} : { ...readSnapshot() };\n delete current[key];\n writeOverrides(current);\n }\n\n function resetAllFlags() {\n writeOverrides({});\n }\n\n function listFlags() {\n return Object.entries(flags).map(([key, def]) => ({\n key,\n ...(def as FlagDef),\n }));\n }\n\n return { useFlag, setFlag, resetFlag, resetAllFlags, listFlags };\n}\n"],"mappings":";AAEA,SAAS,4BAA4B;AAKrC,IAAM,QAAmB,OAAO,OAAO,CAAC,CAAC;AAOlC,SAAS,YAAgC,MAAwC;AACtF,QAAM,EAAE,OAAO,WAAW,IAAI;AAC9B,QAAM,YAAY,iBAAiB,UAAU;AAG7C,MAAI,YAAuC;AAC3C,MAAI,iBAA4B,CAAC;AAEjC,WAAS,eAA0B;AACjC,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAI;AACJ,QAAI;AACF,YAAM,OAAO,aAAa,QAAQ,UAAU;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,UAAW,QAAO;AAC9B,gBAAY;AACZ,QAAI;AACF,uBAAiB,MAAO,KAAK,MAAM,GAAG,IAAkB,CAAC;AAAA,IAC3D,QAAQ;AACN,uBAAiB,CAAC;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAEA,WAAS,eAAe,MAAiB;AACvC,QAAI,OAAO,WAAW,YAAa;AACnC,UAAM,OAAO,KAAK,UAAU,IAAI;AAChC,QAAI;AACF,aAAO,aAAa,QAAQ,YAAY,IAAI;AAAA,IAC9C,QAAQ;AAAA,IAER;AACA,gBAAY;AACZ,qBAAiB;AACjB,WAAO,cAAc,IAAI,MAAM,SAAS,CAAC;AAAA,EAC3C;AAEA,WAAS,UAAU,UAAsB;AACvC,QAAI,OAAO,WAAW,YAAa,QAAO,MAAM;AAAA,IAAC;AACjD,UAAM,UAAU,MAAM;AACpB,kBAAY;AACZ,eAAS;AAAA,IACX;AACA,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,MAAM;AACX,aAAO,oBAAoB,WAAW,OAAO;AAC7C,aAAO,oBAAoB,WAAW,OAAO;AAAA,IAC/C;AAAA,EACF;AAEA,WAAS,oBAA+B;AACtC,WAAO;AAAA,EACT;AAIA,WAAS,QAAqB,KAAiB;AAC7C,UAAM,YAAY,qBAAqB,WAAW,cAAc,iBAAiB;AACjF,QAAI,OAAO,UAAW,QAAO,UAAU,GAAG;AAC1C,UAAM,MAAM,MAAM,GAAG;AACrB,WAAO,IAAI;AAAA,EACb;AAEA,WAAS,QAAQ,KAAc,OAAgB;AAC7C,UAAM,UAAU,OAAO,WAAW,cAAc,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE;AACzE,YAAQ,GAAG,IAAI;AACf,mBAAe,OAAO;AAAA,EACxB;AAEA,WAAS,UAAU,KAAc;AAC/B,UAAM,UAAU,OAAO,WAAW,cAAc,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE;AACzE,WAAO,QAAQ,GAAG;AAClB,mBAAe,OAAO;AAAA,EACxB;AAEA,WAAS,gBAAgB;AACvB,mBAAe,CAAC,CAAC;AAAA,EACnB;AAEA,WAAS,YAAY;AACnB,WAAO,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO;AAAA,MAChD;AAAA,MACA,GAAI;AAAA,IACN,EAAE;AAAA,EACJ;AAEA,SAAO,EAAE,SAAS,SAAS,WAAW,eAAe,UAAU;AACjE;","names":[]}
|
package/package.json
CHANGED
package/dist/createFlags.jsx
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useSyncExternalStore } from "react";
|
|
3
|
-
const EMPTY = Object.freeze({});
|
|
4
|
-
/**
|
|
5
|
-
* Build a per-app flag system. Each consuming app calls this once with its
|
|
6
|
-
* own flag definitions and a unique localStorage namespace. Returns a hook
|
|
7
|
-
* + helpers + a studio panel scoped to those flags.
|
|
8
|
-
*/
|
|
9
|
-
export function createFlags(opts) {
|
|
10
|
-
const { flags, storageKey } = opts;
|
|
11
|
-
const eventName = `flags:changed:${storageKey}`;
|
|
12
|
-
// Cache for stable getSnapshot reference (required by useSyncExternalStore).
|
|
13
|
-
let cachedRaw = undefined;
|
|
14
|
-
let cachedSnapshot = {};
|
|
15
|
-
function readSnapshot() {
|
|
16
|
-
if (typeof window === "undefined")
|
|
17
|
-
return EMPTY;
|
|
18
|
-
let raw;
|
|
19
|
-
try {
|
|
20
|
-
raw = window.localStorage.getItem(storageKey);
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return cachedSnapshot;
|
|
24
|
-
}
|
|
25
|
-
if (raw === cachedRaw)
|
|
26
|
-
return cachedSnapshot;
|
|
27
|
-
cachedRaw = raw;
|
|
28
|
-
try {
|
|
29
|
-
cachedSnapshot = raw ? JSON.parse(raw) : {};
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
cachedSnapshot = {};
|
|
33
|
-
}
|
|
34
|
-
return cachedSnapshot;
|
|
35
|
-
}
|
|
36
|
-
function writeOverrides(next) {
|
|
37
|
-
if (typeof window === "undefined")
|
|
38
|
-
return;
|
|
39
|
-
const json = JSON.stringify(next);
|
|
40
|
-
try {
|
|
41
|
-
window.localStorage.setItem(storageKey, json);
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
// ignore quota / private mode errors
|
|
45
|
-
}
|
|
46
|
-
cachedRaw = json;
|
|
47
|
-
cachedSnapshot = next;
|
|
48
|
-
window.dispatchEvent(new Event(eventName));
|
|
49
|
-
}
|
|
50
|
-
function subscribe(callback) {
|
|
51
|
-
if (typeof window === "undefined")
|
|
52
|
-
return () => { };
|
|
53
|
-
const handler = () => {
|
|
54
|
-
cachedRaw = undefined;
|
|
55
|
-
callback();
|
|
56
|
-
};
|
|
57
|
-
window.addEventListener(eventName, handler);
|
|
58
|
-
window.addEventListener("storage", handler);
|
|
59
|
-
return () => {
|
|
60
|
-
window.removeEventListener(eventName, handler);
|
|
61
|
-
window.removeEventListener("storage", handler);
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function getServerSnapshot() {
|
|
65
|
-
return EMPTY;
|
|
66
|
-
}
|
|
67
|
-
function useFlag(key) {
|
|
68
|
-
const overrides = useSyncExternalStore(subscribe, readSnapshot, getServerSnapshot);
|
|
69
|
-
if (key in overrides)
|
|
70
|
-
return overrides[key];
|
|
71
|
-
const def = flags[key];
|
|
72
|
-
return def.default;
|
|
73
|
-
}
|
|
74
|
-
function setFlag(key, value) {
|
|
75
|
-
const current = typeof window === "undefined" ? {} : { ...readSnapshot() };
|
|
76
|
-
current[key] = value;
|
|
77
|
-
writeOverrides(current);
|
|
78
|
-
}
|
|
79
|
-
function resetFlag(key) {
|
|
80
|
-
const current = typeof window === "undefined" ? {} : { ...readSnapshot() };
|
|
81
|
-
delete current[key];
|
|
82
|
-
writeOverrides(current);
|
|
83
|
-
}
|
|
84
|
-
function resetAllFlags() {
|
|
85
|
-
writeOverrides({});
|
|
86
|
-
}
|
|
87
|
-
function listFlags() {
|
|
88
|
-
return Object.entries(flags).map(([key, def]) => ({
|
|
89
|
-
key,
|
|
90
|
-
...def,
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
return { useFlag, setFlag, resetFlag, resetAllFlags, listFlags };
|
|
94
|
-
}
|
|
95
|
-
//# sourceMappingURL=createFlags.jsx.map
|
package/dist/createFlags.jsx.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createFlags.jsx","sourceRoot":"","sources":["../src/createFlags.tsx"],"names":[],"mappings":"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"}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/createFlags.tsx"],"sourcesContent":["\"use client\";\n\nimport { useSyncExternalStore } from \"react\";\nimport type { FlagDef, FlagsMap } from \"./index.js\";\n\ntype Overrides = Record<string, unknown>;\n\nconst EMPTY: Overrides = Object.freeze({}) as Overrides;\n\n/**\n * Build a per-app flag system. Each consuming app calls this once with its\n * own flag definitions and a unique localStorage namespace. Returns a hook\n * + helpers + a studio panel scoped to those flags.\n */\nexport function createFlags<F extends FlagsMap>(opts: { flags: F; storageKey: string }) {\n const { flags, storageKey } = opts;\n const eventName = `flags:changed:${storageKey}`;\n\n // Cache for stable getSnapshot reference (required by useSyncExternalStore).\n let cachedRaw: string | null | undefined = undefined;\n let cachedSnapshot: Overrides = {};\n\n function readSnapshot(): Overrides {\n if (typeof window === \"undefined\") return EMPTY;\n let raw: string | null;\n try {\n raw = window.localStorage.getItem(storageKey);\n } catch {\n return cachedSnapshot;\n }\n if (raw === cachedRaw) return cachedSnapshot;\n cachedRaw = raw;\n try {\n cachedSnapshot = raw ? (JSON.parse(raw) as Overrides) : {};\n } catch {\n cachedSnapshot = {};\n }\n return cachedSnapshot;\n }\n\n function writeOverrides(next: Overrides) {\n if (typeof window === \"undefined\") return;\n const json = JSON.stringify(next);\n try {\n window.localStorage.setItem(storageKey, json);\n } catch {\n // ignore quota / private mode errors\n }\n cachedRaw = json;\n cachedSnapshot = next;\n window.dispatchEvent(new Event(eventName));\n }\n\n function subscribe(callback: () => void) {\n if (typeof window === \"undefined\") return () => {};\n const handler = () => {\n cachedRaw = undefined;\n callback();\n };\n window.addEventListener(eventName, handler);\n window.addEventListener(\"storage\", handler);\n return () => {\n window.removeEventListener(eventName, handler);\n window.removeEventListener(\"storage\", handler);\n };\n }\n\n function getServerSnapshot(): Overrides {\n return EMPTY;\n }\n\n type FlagKey = keyof F & string;\n\n function useFlag<T = unknown>(key: FlagKey): T {\n const overrides = useSyncExternalStore(subscribe, readSnapshot, getServerSnapshot);\n if (key in overrides) return overrides[key] as T;\n const def = flags[key] as FlagDef;\n return def.default as T;\n }\n\n function setFlag(key: FlagKey, value: unknown) {\n const current = typeof window === \"undefined\" ? {} : { ...readSnapshot() };\n current[key] = value;\n writeOverrides(current);\n }\n\n function resetFlag(key: FlagKey) {\n const current = typeof window === \"undefined\" ? {} : { ...readSnapshot() };\n delete current[key];\n writeOverrides(current);\n }\n\n function resetAllFlags() {\n writeOverrides({});\n }\n\n function listFlags() {\n return Object.entries(flags).map(([key, def]) => ({\n key,\n ...(def as FlagDef),\n }));\n }\n\n return { useFlag, setFlag, resetFlag, resetAllFlags, listFlags };\n}\n"],"mappings":";AAEA,SAAS,4BAA4B;AAKrC,IAAM,QAAmB,OAAO,OAAO,CAAC,CAAC;AAOlC,SAAS,YAAgC,MAAwC;AACtF,QAAM,EAAE,OAAO,WAAW,IAAI;AAC9B,QAAM,YAAY,iBAAiB,UAAU;AAG7C,MAAI,YAAuC;AAC3C,MAAI,iBAA4B,CAAC;AAEjC,WAAS,eAA0B;AACjC,QAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAI;AACJ,QAAI;AACF,YAAM,OAAO,aAAa,QAAQ,UAAU;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AACA,QAAI,QAAQ,UAAW,QAAO;AAC9B,gBAAY;AACZ,QAAI;AACF,uBAAiB,MAAO,KAAK,MAAM,GAAG,IAAkB,CAAC;AAAA,IAC3D,QAAQ;AACN,uBAAiB,CAAC;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AAEA,WAAS,eAAe,MAAiB;AACvC,QAAI,OAAO,WAAW,YAAa;AACnC,UAAM,OAAO,KAAK,UAAU,IAAI;AAChC,QAAI;AACF,aAAO,aAAa,QAAQ,YAAY,IAAI;AAAA,IAC9C,QAAQ;AAAA,IAER;AACA,gBAAY;AACZ,qBAAiB;AACjB,WAAO,cAAc,IAAI,MAAM,SAAS,CAAC;AAAA,EAC3C;AAEA,WAAS,UAAU,UAAsB;AACvC,QAAI,OAAO,WAAW,YAAa,QAAO,MAAM;AAAA,IAAC;AACjD,UAAM,UAAU,MAAM;AACpB,kBAAY;AACZ,eAAS;AAAA,IACX;AACA,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,iBAAiB,WAAW,OAAO;AAC1C,WAAO,MAAM;AACX,aAAO,oBAAoB,WAAW,OAAO;AAC7C,aAAO,oBAAoB,WAAW,OAAO;AAAA,IAC/C;AAAA,EACF;AAEA,WAAS,oBAA+B;AACtC,WAAO;AAAA,EACT;AAIA,WAAS,QAAqB,KAAiB;AAC7C,UAAM,YAAY,qBAAqB,WAAW,cAAc,iBAAiB;AACjF,QAAI,OAAO,UAAW,QAAO,UAAU,GAAG;AAC1C,UAAM,MAAM,MAAM,GAAG;AACrB,WAAO,IAAI;AAAA,EACb;AAEA,WAAS,QAAQ,KAAc,OAAgB;AAC7C,UAAM,UAAU,OAAO,WAAW,cAAc,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE;AACzE,YAAQ,GAAG,IAAI;AACf,mBAAe,OAAO;AAAA,EACxB;AAEA,WAAS,UAAU,KAAc;AAC/B,UAAM,UAAU,OAAO,WAAW,cAAc,CAAC,IAAI,EAAE,GAAG,aAAa,EAAE;AACzE,WAAO,QAAQ,GAAG;AAClB,mBAAe,OAAO;AAAA,EACxB;AAEA,WAAS,gBAAgB;AACvB,mBAAe,CAAC,CAAC;AAAA,EACnB;AAEA,WAAS,YAAY;AACnB,WAAO,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO;AAAA,MAChD;AAAA,MACA,GAAI;AAAA,IACN,EAAE;AAAA,EACJ;AAEA,SAAO,EAAE,SAAS,SAAS,WAAW,eAAe,UAAU;AACjE;","names":[]}
|