ffdev 0.0.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.
@@ -0,0 +1,22 @@
1
+ import { FlagDef } from '../core/flag-def.js';
2
+ import { Store } from '../core/store.js';
3
+ export declare const BAR_SENTINEL = "__FFDEV_BAR_SENTINEL__";
4
+ export interface BarController {
5
+ mount(): void;
6
+ unmount(): void;
7
+ }
8
+ export declare function mountBar(isDev?: boolean): BarController;
9
+ declare global {
10
+ interface Window {
11
+ __FFDEV__?: {
12
+ open(): void;
13
+ close(): void;
14
+ setFlag(name: string, value: unknown): void;
15
+ getFlags(): Record<string, unknown>;
16
+ status(): string;
17
+ refetchRemote(): Promise<void>;
18
+ };
19
+ }
20
+ }
21
+ export declare function attachGlobalApi(store: Store, defs: Record<string, FlagDef<unknown>>, bar: BarController): void;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bar/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE9C,eAAO,MAAM,YAAY,2BAA2B,CAAC;AAErD,MAAM,WAAW,aAAa;IAC7B,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,IAAI,IAAI,CAAC;CAChB;AAED,wBAAgB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,aAAa,CA4BvD;AAED,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,SAAS,CAAC,EAAE;YACX,IAAI,IAAI,IAAI,CAAC;YACb,KAAK,IAAI,IAAI,CAAC;YACd,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;YAC5C,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACpC,MAAM,IAAI,MAAM,CAAC;YACjB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;SAC/B,CAAC;KACF;CACD;AAED,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,EACtC,GAAG,EAAE,aAAa,GAChB,IAAI,CA6BN"}
@@ -0,0 +1,17 @@
1
+ export interface FlagDef<V> {
2
+ readonly kind: 'boolean' | 'enum';
3
+ readonly defaultValue: V;
4
+ validate(value: unknown): value is V;
5
+ }
6
+ declare function booleanFlag(opts: {
7
+ default: boolean;
8
+ }): FlagDef<boolean>;
9
+ declare function enumFlag<const T extends readonly string[]>(variants: T, opts: {
10
+ default: T[number];
11
+ }): FlagDef<T[number]>;
12
+ export declare const flag: {
13
+ readonly boolean: typeof booleanFlag;
14
+ readonly enum: typeof enumFlag;
15
+ };
16
+ export {};
17
+ //# sourceMappingURL=flag-def.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flag-def.d.ts","sourceRoot":"","sources":["../../src/core/flag-def.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO,CAAC,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC;CACrC;AAED,iBAAS,WAAW,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAQjE;AAED,iBAAS,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,EAClD,QAAQ,EAAE,CAAC,EACX,IAAI,EAAE;IAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;CAAE,GAC1B,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CASpB;AAED,eAAO,MAAM,IAAI;;;CAGP,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Source } from './source.js';
2
+ export declare class LocalSource implements Source {
3
+ private readonly prefix;
4
+ constructor(namespace: string);
5
+ read(flagName: string): unknown | undefined;
6
+ write(flagName: string, value: unknown | undefined): void;
7
+ subscribe(listener: () => void): () => void;
8
+ }
9
+ //# sourceMappingURL=local-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-source.d.ts","sourceRoot":"","sources":["../../src/core/local-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,qBAAa,WAAY,YAAW,MAAM;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,SAAS,EAAE,MAAM;IAI7B,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAU3C,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI;IASzD,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;CAS3C"}
@@ -0,0 +1,9 @@
1
+ import { FlagDef } from './flag-def.js';
2
+ import { Source } from './source.js';
3
+ export declare class QuerySource implements Source {
4
+ private namespace;
5
+ private getSearchParams;
6
+ constructor(namespace: string, getSearchParams: () => URLSearchParams);
7
+ read(flagName: string, def: FlagDef<unknown>): unknown | undefined;
8
+ }
9
+ //# sourceMappingURL=query-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-source.d.ts","sourceRoot":"","sources":["../../src/core/query-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,qBAAa,WAAY,YAAW,MAAM;IAExC,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,eAAe;gBADf,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,eAAe;IAG/C,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS;CAmBlE"}
@@ -0,0 +1,11 @@
1
+ import { FlagDef } from './flag-def.js';
2
+ import { Source } from './source.js';
3
+ export type RemoteConfig = string | (() => Promise<Record<string, unknown>>);
4
+ export declare class RemoteSource implements Source {
5
+ private cache;
6
+ private fetcher;
7
+ constructor(config: RemoteConfig);
8
+ read(flagName: string, _def: FlagDef<unknown>): unknown | undefined;
9
+ fetch(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=remote-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-source.d.ts","sourceRoot":"","sources":["../../src/core/remote-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7E,qBAAa,YAAa,YAAW,MAAM;IAC1C,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,OAAO,CAAyC;gBAE5C,MAAM,EAAE,YAAY;IAWhC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS;IAI7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK5B"}
@@ -0,0 +1,4 @@
1
+ import { FlagDef } from './flag-def.js';
2
+ import { Source } from './source.js';
3
+ export declare function resolve<V>(flagName: string, def: FlagDef<V>, sources: readonly Source[]): V;
4
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/core/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,wBAAgB,OAAO,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACf,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,CAAC,CAQH"}
@@ -0,0 +1,11 @@
1
+ import { FlagDef } from './flag-def.js';
2
+ export interface Source {
3
+ read(flagName: string, def: FlagDef<unknown>): unknown | undefined;
4
+ subscribe?(listener: () => void): () => void;
5
+ }
6
+ export declare class DefaultSource implements Source {
7
+ private defs;
8
+ constructor(defs: Record<string, FlagDef<unknown>>);
9
+ read(flagName: string): unknown | undefined;
10
+ }
11
+ //# sourceMappingURL=source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../src/core/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,MAAM;IACtB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC;IACnE,SAAS,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC7C;AAED,qBAAa,aAAc,YAAW,MAAM;IAC/B,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;CAI3C"}
@@ -0,0 +1,16 @@
1
+ import { FlagDef } from './flag-def.js';
2
+ import { LocalSource } from './local-source.js';
3
+ import { RemoteSource } from './remote-source.js';
4
+ import { Source } from './source.js';
5
+ export type Status = 'idle' | 'loading' | 'ready' | 'error';
6
+ export interface Store {
7
+ getSnapshot(): Record<string, unknown>;
8
+ getFlagSnapshot(flagName: string): unknown;
9
+ subscribe(listener: () => void): () => void;
10
+ getStatus(): Status;
11
+ notify(): void;
12
+ setLocal(flagName: string, value: unknown | undefined): void;
13
+ refetchRemote(): Promise<void>;
14
+ }
15
+ export declare function createStore(defs: Record<string, FlagDef<unknown>>, sources: readonly Source[], localSource?: LocalSource, remote?: RemoteSource): Store;
16
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/core/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5D,MAAM,WAAW,KAAK;IACrB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,SAAS,IAAI,MAAM,CAAC;IACpB,MAAM,IAAI,IAAI,CAAC;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC;IAC7D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,wBAAgB,WAAW,CAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,EACtC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,WAAW,CAAC,EAAE,WAAW,EACzB,MAAM,CAAC,EAAE,YAAY,GACnB,KAAK,CA6EP"}
@@ -0,0 +1,170 @@
1
+ var y = Object.defineProperty;
2
+ var F = (r, e, t) => e in r ? y(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
3
+ var S = (r, e, t) => F(r, typeof e != "symbol" ? e + "" : e, t);
4
+ import { useSyncExternalStore as g } from "react";
5
+ import { QuerySource as x } from "./index.js";
6
+ class L {
7
+ constructor(e) {
8
+ S(this, "prefix");
9
+ this.prefix = `${e}:`;
10
+ }
11
+ read(e) {
12
+ const t = localStorage.getItem(this.prefix + e);
13
+ if (t !== null)
14
+ try {
15
+ return JSON.parse(t);
16
+ } catch {
17
+ return;
18
+ }
19
+ }
20
+ write(e, t) {
21
+ const n = this.prefix + e;
22
+ t === void 0 ? localStorage.removeItem(n) : localStorage.setItem(n, JSON.stringify(t));
23
+ }
24
+ subscribe(e) {
25
+ const t = (n) => {
26
+ var c;
27
+ (c = n.key) != null && c.startsWith(this.prefix) && e();
28
+ };
29
+ return window.addEventListener("storage", t), () => window.removeEventListener("storage", t);
30
+ }
31
+ }
32
+ class P {
33
+ constructor(e) {
34
+ S(this, "cache");
35
+ S(this, "fetcher");
36
+ this.fetcher = typeof e == "string" ? () => fetch(e).then((t) => {
37
+ if (!t.ok) throw new Error(`HTTP ${t.status}`);
38
+ return t.json();
39
+ }) : e;
40
+ }
41
+ read(e, t) {
42
+ var n;
43
+ return (n = this.cache) == null ? void 0 : n[e];
44
+ }
45
+ async fetch() {
46
+ this.cache = void 0;
47
+ const e = await this.fetcher();
48
+ this.cache = e;
49
+ }
50
+ }
51
+ class R {
52
+ constructor(e) {
53
+ this.defs = e;
54
+ }
55
+ read(e) {
56
+ const t = this.defs[e];
57
+ return t == null ? void 0 : t.defaultValue;
58
+ }
59
+ }
60
+ function k(r, e, t) {
61
+ for (const n of t) {
62
+ const c = n.read(r, e);
63
+ if (c !== void 0 && e.validate(c))
64
+ return c;
65
+ }
66
+ return e.defaultValue;
67
+ }
68
+ function D(r, e, t, n) {
69
+ const c = /* @__PURE__ */ new Set();
70
+ let h = l();
71
+ const u = { ...h };
72
+ let f = n ? "loading" : "idle";
73
+ function l() {
74
+ const s = {};
75
+ for (const o of Object.keys(r))
76
+ s[o] = k(o, r[o], e);
77
+ return s;
78
+ }
79
+ function i() {
80
+ const s = l();
81
+ for (const o of Object.keys(s))
82
+ s[o] !== u[o] && (u[o] = s[o]);
83
+ h = s;
84
+ for (const o of c)
85
+ o();
86
+ }
87
+ function d(s) {
88
+ return s.fetch().then(
89
+ () => {
90
+ f = "ready", i();
91
+ },
92
+ (o) => {
93
+ console.warn("[ffdev] Remote fetch failed:", o), f = "error", i();
94
+ }
95
+ );
96
+ }
97
+ n && d(n);
98
+ function a() {
99
+ return n ? (f = "loading", i(), d(n)) : Promise.resolve();
100
+ }
101
+ return {
102
+ getSnapshot() {
103
+ return h;
104
+ },
105
+ getFlagSnapshot(s) {
106
+ return u[s];
107
+ },
108
+ subscribe(s) {
109
+ return c.add(s), () => {
110
+ c.delete(s);
111
+ };
112
+ },
113
+ getStatus() {
114
+ return f;
115
+ },
116
+ notify: i,
117
+ setLocal(s, o) {
118
+ t && (t.write(s, o), i());
119
+ },
120
+ refetchRemote: a
121
+ };
122
+ }
123
+ const E = () => new URL(window.location.href).searchParams;
124
+ function I(r, e) {
125
+ const { flags: t } = r, n = r.namespace ?? "ffdev", { remote: c } = r, h = (e == null ? void 0 : e.getSearchParams) ?? E, u = new L(n), f = new x(n, h), l = c ? new P(c) : void 0, i = new R(t), d = [
126
+ f,
127
+ u,
128
+ ...l ? [l] : [],
129
+ i
130
+ ], a = D(t, d, u, l);
131
+ u.subscribe(() => a.notify());
132
+ function s(m) {
133
+ return g(
134
+ a.subscribe,
135
+ () => a.getFlagSnapshot(m)
136
+ );
137
+ }
138
+ function o() {
139
+ return g(
140
+ a.subscribe,
141
+ () => a.getSnapshot()
142
+ );
143
+ }
144
+ function w(m, b) {
145
+ a.setLocal(m, b);
146
+ }
147
+ function p() {
148
+ return g(a.subscribe, () => a.getStatus());
149
+ }
150
+ function v() {
151
+ return a.refetchRemote();
152
+ }
153
+ return {
154
+ useFlag: s,
155
+ useFlags: o,
156
+ setFlag: w,
157
+ useFFDevStatus: p,
158
+ refetchRemote: v,
159
+ store: a,
160
+ defs: t
161
+ };
162
+ }
163
+ function N(r, e) {
164
+ const { store: t, defs: n, ...c } = I(r, e);
165
+ return c;
166
+ }
167
+ export {
168
+ I as a,
169
+ N as c
170
+ };
@@ -0,0 +1,5 @@
1
+ export { defineConfig, flag, QuerySource } from '../index.js';
2
+ export type { FlagDef, Source } from '../index.js';
3
+ export { createFFDev } from '../react/create-ffdev.js';
4
+ export type { FFDevOptions } from '../react/create-ffdev.js';
5
+ //# sourceMappingURL=react-headless.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-headless.d.ts","sourceRoot":"","sources":["../../src/entries/react-headless.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { QuerySource as o, defineConfig as f, flag as a } from "../index.js";
2
+ import { c as t } from "../create-ffdev-B2ww_7Y1.js";
3
+ export {
4
+ o as QuerySource,
5
+ t as createFFDev,
6
+ f as defineConfig,
7
+ a as flag
8
+ };
@@ -0,0 +1,16 @@
1
+ import { BAR_SENTINEL, mountBar } from '../bar/index.js';
2
+ import { FFDevConfig, FFDevOptions } from '../react/create-ffdev.js';
3
+ export { defineConfig, flag, QuerySource } from '../index.js';
4
+ export type { FlagDef, Source } from '../index.js';
5
+ export type { FFDevOptions };
6
+ export { BAR_SENTINEL, mountBar };
7
+ export declare function createFFDev<C extends FFDevConfig>(config: C, options?: FFDevOptions): {
8
+ useFlag: <K extends keyof C["flags"] & string>(name: K) => C["flags"][K] extends infer T ? T extends C["flags"][K] ? T extends import('./react.js').FlagDef<infer V> ? V : never : never : never;
9
+ useFlags: () => C["flags"] extends infer T extends {
10
+ [x: string]: import('./react.js').FlagDef<unknown>;
11
+ } ? { [K in keyof T]: T[K] extends infer T_1 ? T_1 extends T[K] ? T_1 extends import('./react.js').FlagDef<infer V> ? V : never : never : never; } : never;
12
+ setFlag: <K extends keyof C["flags"] & string>(name: K, value: (C["flags"][K] extends infer T ? T extends C["flags"][K] ? T extends import('./react.js').FlagDef<infer V> ? V : never : never : never) | undefined) => void;
13
+ useFFDevStatus: () => import('../core/store.js').Status;
14
+ refetchRemote: () => Promise<void>;
15
+ };
16
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/entries/react.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAmB,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,YAAY,EAEjB,MAAM,0BAA0B,CAAC;AAElC,YAAY,EAAE,YAAY,EAAE,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;AAElC,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAChD,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,YAAY;;;;;;;;EAMtB"}
@@ -0,0 +1,56 @@
1
+ import { QuerySource as _, defineConfig as m, flag as v } from "../index.js";
2
+ import { a as f } from "../create-ffdev-B2ww_7Y1.js";
3
+ const c = "__FFDEV_BAR_SENTINEL__";
4
+ function i(n) {
5
+ const r = n ?? (typeof process < "u" ? process.env.NODE_ENV !== "production" : !0);
6
+ let t = null;
7
+ function e() {
8
+ t || (t = document.createElement("div"), t.setAttribute("data-ffdev-bar", c), t.textContent = "ffdev bar [stub]", document.body.appendChild(t));
9
+ }
10
+ function o() {
11
+ t && (t.remove(), t = null);
12
+ }
13
+ return r && e(), { mount: e, unmount: o };
14
+ }
15
+ function a(n, r, t) {
16
+ window.__FFDEV__ = {
17
+ open() {
18
+ t.mount();
19
+ },
20
+ close() {
21
+ t.unmount();
22
+ },
23
+ setFlag(e, o) {
24
+ if (!(e in r)) {
25
+ console.warn(`[ffdev] Unknown flag: "${e}"`);
26
+ return;
27
+ }
28
+ if (o !== void 0 && !r[e].validate(o)) {
29
+ console.warn(`[ffdev] Invalid value for flag "${e}":`, o);
30
+ return;
31
+ }
32
+ n.setLocal(e, o);
33
+ },
34
+ getFlags() {
35
+ return n.getSnapshot();
36
+ },
37
+ status() {
38
+ return n.getStatus();
39
+ },
40
+ refetchRemote() {
41
+ return n.refetchRemote();
42
+ }
43
+ };
44
+ }
45
+ function l(n, r) {
46
+ const { store: t, defs: e, ...o } = f(n, r), u = i();
47
+ return a(t, e, u), o;
48
+ }
49
+ export {
50
+ c as BAR_SENTINEL,
51
+ _ as QuerySource,
52
+ l as createFFDev,
53
+ m as defineConfig,
54
+ v as flag,
55
+ i as mountBar
56
+ };
@@ -0,0 +1,13 @@
1
+ import { FlagDef } from './core/flag-def.js';
2
+ import { RemoteConfig } from './core/remote-source.js';
3
+ export { flag } from './core/flag-def.js';
4
+ export type { FlagDef } from './core/flag-def.js';
5
+ export type { Source } from './core/source.js';
6
+ export { QuerySource } from './core/query-source.js';
7
+ interface FFDevConfig {
8
+ namespace?: string;
9
+ remote?: RemoteConfig;
10
+ flags: Record<string, FlagDef<unknown>>;
11
+ }
12
+ export declare function defineConfig<C extends FFDevConfig>(config: C): C;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,UAAU,WAAW;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;CACxC;AAED,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAEhE"}
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ function u(t) {
2
+ return {
3
+ kind: "boolean",
4
+ defaultValue: t.default,
5
+ validate(e) {
6
+ return typeof e == "boolean";
7
+ }
8
+ };
9
+ }
10
+ function i(t, e) {
11
+ const n = new Set(t);
12
+ return {
13
+ kind: "enum",
14
+ defaultValue: e.default,
15
+ validate(a) {
16
+ return typeof a == "string" && n.has(a);
17
+ }
18
+ };
19
+ }
20
+ const l = {
21
+ boolean: u,
22
+ enum: i
23
+ };
24
+ class s {
25
+ constructor(e, n) {
26
+ this.namespace = e, this.getSearchParams = n;
27
+ }
28
+ read(e, n) {
29
+ const a = this.getSearchParams(), o = `${this.namespace}.${e}`, r = a.get(o);
30
+ if (r !== null) {
31
+ if (n.kind === "boolean")
32
+ return r === "true" ? !0 : r === "false" ? !1 : void 0;
33
+ if (n.kind === "enum")
34
+ return n.validate(r) ? r : void 0;
35
+ }
36
+ }
37
+ }
38
+ function f(t) {
39
+ return t;
40
+ }
41
+ export {
42
+ s as QuerySource,
43
+ f as defineConfig,
44
+ l as flag
45
+ };
@@ -0,0 +1,34 @@
1
+ import { FlagDef } from '../core/flag-def.js';
2
+ import { RemoteConfig } from '../core/remote-source.js';
3
+ import { Status } from '../core/store.js';
4
+ type FlagsConfig = Record<string, FlagDef<unknown>>;
5
+ type FlagValue<F> = F extends FlagDef<infer V> ? V : never;
6
+ type FlagsSnapshot<F extends FlagsConfig> = {
7
+ [K in keyof F]: FlagValue<F[K]>;
8
+ };
9
+ export interface FFDevConfig {
10
+ namespace?: string;
11
+ remote?: RemoteConfig;
12
+ flags: FlagsConfig;
13
+ }
14
+ export interface FFDevOptions {
15
+ getSearchParams?: () => URLSearchParams;
16
+ }
17
+ export declare function createFFDevInternal<C extends FFDevConfig>(config: C, options?: FFDevOptions): {
18
+ useFlag: <K extends keyof C["flags"] & string>(name: K) => FlagValue<C["flags"][K]>;
19
+ useFlags: () => FlagsSnapshot<C["flags"]>;
20
+ setFlag: <K extends keyof C["flags"] & string>(name: K, value: FlagValue<C["flags"][K]> | undefined) => void;
21
+ useFFDevStatus: () => Status;
22
+ refetchRemote: () => Promise<void>;
23
+ store: import('../core/store.js').Store;
24
+ defs: FlagsConfig;
25
+ };
26
+ export declare function createFFDev<C extends FFDevConfig>(config: C, options?: FFDevOptions): {
27
+ useFlag: <K extends keyof C["flags"] & string>(name: K) => FlagValue<C["flags"][K]>;
28
+ useFlags: () => FlagsSnapshot<C["flags"]>;
29
+ setFlag: <K extends keyof C["flags"] & string>(name: K, value: FlagValue<C["flags"][K]> | undefined) => void;
30
+ useFFDevStatus: () => Status;
31
+ refetchRemote: () => Promise<void>;
32
+ };
33
+ export {};
34
+ //# sourceMappingURL=create-ffdev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ffdev.d.ts","sourceRoot":"","sources":["../../src/react/create-ffdev.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,KAAK,MAAM,EAAe,MAAM,kBAAkB,CAAC;AAE5D,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AAEpD,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE3D,KAAK,aAAa,CAAC,CAAC,SAAS,WAAW,IAAI;KAC1C,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC5B,eAAe,CAAC,EAAE,MAAM,eAAe,CAAC;CACxC;AAKD,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,WAAW,EACxD,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,YAAY;cAsBL,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,MAAM,QAC7C,CAAC,KACL,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;oBAON,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;cAO7B,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,MAAM,QAC7C,CAAC,SACA,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,KACzC,IAAI;0BAIoB,MAAM;yBAIP,OAAO,CAAC,IAAI,CAAC;;;EAavC;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,WAAW,EAChD,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,YAAY;cA5CL,CAAC;;cAgBD,CAAC,6FAGf,IAAI;0BAIoB,MAAM;yBAIP,OAAO,CAAC,IAAI,CAAC;EAqBvC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=create-ffdev.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ffdev.test.d.ts","sourceRoot":"","sources":["../../src/react/create-ffdev.test.tsx"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "ffdev",
3
+ "version": "0.0.0",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "sideEffects": false,
7
+ "engines": {
8
+ "node": ">=18"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ },
15
+ "./react": {
16
+ "types": "./dist/entries/react.d.ts",
17
+ "import": "./dist/entries/react.js"
18
+ },
19
+ "./react/headless": {
20
+ "types": "./dist/entries/react-headless.d.ts",
21
+ "import": "./dist/entries/react-headless.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "scripts": {
28
+ "build": "vite build",
29
+ "typecheck": "tsc --noEmit"
30
+ },
31
+ "peerDependencies": {
32
+ "react": ">=18.0.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "^19.2.14",
36
+ "react": "^19.1.0",
37
+ "vite": "^6.3.5",
38
+ "vite-plugin-dts": "^4.5.4"
39
+ }
40
+ }