@voltro/plugin-flags 0.86.0 → 0.87.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/CHANGELOG.md +5321 -0
- package/README.md +106 -0
- package/THIRD-PARTY-NOTICES.md +1132 -13
- package/dist/config-inspect.d.ts +33 -0
- package/dist/config-inspect.js +29 -0
- package/dist/config-port.d.ts +247 -0
- package/dist/config-port.js +125 -0
- package/dist/config-testing.d.ts +336 -0
- package/dist/config-testing.js +114 -0
- package/dist/config.d.ts +250 -0
- package/dist/config.js +235 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +15 -2
- package/dist/index.d.ts +164 -1
- package/dist/index.js +327 -156
- package/dist/rpc.d.ts +14 -0
- package/dist/rpc.js +29 -14
- package/dist/store.js +37 -1
- package/dist/web.d.ts +24 -0
- package/dist/web.js +14 -8
- package/package.json +26 -6
package/dist/rpc.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ConfigError as e } from "./errors.js";
|
|
2
|
+
import { Schema as t } from "effect";
|
|
3
|
+
import { defineQuery as n } from "@voltro/protocol";
|
|
3
4
|
//#region src/rpc.ts
|
|
4
|
-
var
|
|
5
|
+
var r = "@voltro/plugin-flags", i = n({
|
|
5
6
|
name: "flags.evaluate",
|
|
6
|
-
input:
|
|
7
|
-
output:
|
|
7
|
+
input: t.Struct({}),
|
|
8
|
+
output: t.Record(t.String, t.Boolean),
|
|
8
9
|
openAccess: "per-caller flag evaluation: returns only the values computed for the calling subject; every session (incl. anonymous) evaluates its own flags"
|
|
9
|
-
}),
|
|
10
|
-
name:
|
|
11
|
-
value:
|
|
12
|
-
enabled:
|
|
13
|
-
}),
|
|
10
|
+
}), a = t.Struct({
|
|
11
|
+
name: t.String,
|
|
12
|
+
value: t.Unknown,
|
|
13
|
+
enabled: t.Boolean
|
|
14
|
+
}), o = n({
|
|
14
15
|
name: "flags.variants",
|
|
15
|
-
input:
|
|
16
|
-
output:
|
|
16
|
+
input: t.Struct({}),
|
|
17
|
+
output: t.Record(t.String, a),
|
|
17
18
|
openAccess: "per-caller variant resolution: returns only the variants served to the calling subject; every session (incl. anonymous) evaluates its own flags"
|
|
18
|
-
}),
|
|
19
|
+
}), s = [{
|
|
19
20
|
tag: "flags.evaluate",
|
|
20
21
|
kind: "query",
|
|
21
22
|
import: {
|
|
@@ -29,6 +30,20 @@ var n = "@voltro/plugin-flags", r = t({
|
|
|
29
30
|
module: "@voltro/plugin-flags/rpc",
|
|
30
31
|
name: "evaluateVariantsDescriptor"
|
|
31
32
|
}
|
|
33
|
+
}], c = n({
|
|
34
|
+
name: "config.mine",
|
|
35
|
+
input: t.Struct({}),
|
|
36
|
+
output: t.Record(t.String, t.Unknown),
|
|
37
|
+
error: e,
|
|
38
|
+
source: ["_voltro_feature_flags"],
|
|
39
|
+
openAccess: "Only declared public Config values computed from the actual calling subject; no subject selector or private keys."
|
|
40
|
+
}), l = [{
|
|
41
|
+
tag: "config.mine",
|
|
42
|
+
kind: "query",
|
|
43
|
+
import: {
|
|
44
|
+
module: "@voltro/plugin-flags/rpc",
|
|
45
|
+
name: "configMineDescriptor"
|
|
46
|
+
}
|
|
32
47
|
}];
|
|
33
48
|
//#endregion
|
|
34
|
-
export {
|
|
49
|
+
export { r as BASE_NAME, c as configMineDescriptor, l as configRpcClientImports, i as evaluateDescriptor, o as evaluateVariantsDescriptor, s as flagsRpcClientImports };
|
package/dist/store.js
CHANGED
|
@@ -19,6 +19,8 @@ var d = "_voltro_feature_flag_audit", f = "_voltro_feature_flags", p = c(f, {
|
|
|
19
19
|
enabled: t(),
|
|
20
20
|
previousEnabled: t().nullable(),
|
|
21
21
|
actorId: l().nullable(),
|
|
22
|
+
value: o().nullable(),
|
|
23
|
+
previousValue: o().nullable(),
|
|
22
24
|
at: u().default("now")
|
|
23
25
|
}).index("byFlagAuditFlag", ["flag"]).index("byFlagAuditAt", ["at"]), h = (e, t) => {
|
|
24
26
|
let n = { ...e };
|
|
@@ -114,6 +116,8 @@ var d = "_voltro_feature_flag_audit", f = "_voltro_feature_flags", p = c(f, {
|
|
|
114
116
|
enabled: e.enabled === !0 || e.enabled === 1,
|
|
115
117
|
previousEnabled: e.previousEnabled == null ? null : e.previousEnabled === !0 || e.previousEnabled === 1,
|
|
116
118
|
actorId: e.actorId ?? null,
|
|
119
|
+
...e.value == null ? {} : { value: e.value },
|
|
120
|
+
...e.previousValue == null ? {} : { previousValue: e.previousValue },
|
|
117
121
|
at: e.at instanceof Date ? e.at : new Date(String(e.at))
|
|
118
122
|
}), T = (e) => ({
|
|
119
123
|
record: async (t) => {
|
|
@@ -123,6 +127,8 @@ var d = "_voltro_feature_flag_audit", f = "_voltro_feature_flags", p = c(f, {
|
|
|
123
127
|
enabled: t.enabled,
|
|
124
128
|
previousEnabled: t.previousEnabled,
|
|
125
129
|
actorId: t.actorId,
|
|
130
|
+
value: t.value ?? null,
|
|
131
|
+
previousValue: t.previousValue ?? null,
|
|
126
132
|
at: t.at
|
|
127
133
|
});
|
|
128
134
|
},
|
|
@@ -131,6 +137,36 @@ var d = "_voltro_feature_flag_audit", f = "_voltro_feature_flags", p = c(f, {
|
|
|
131
137
|
return t?.flag != null && (n = n.where(r("flag", t.flag))), t?.limit != null && (n = n.limit(t.limit)), (await e.query(n.descriptor)).map(w);
|
|
132
138
|
}
|
|
133
139
|
}), E = async (e, t, i, a, o) => {
|
|
140
|
+
await e.transactional(async (e) => {
|
|
141
|
+
await e.insertIgnore(f, {
|
|
142
|
+
...C(x(t, i)),
|
|
143
|
+
id: n("flag", crypto.randomUUID())
|
|
144
|
+
}, { conflictColumns: ["key"] });
|
|
145
|
+
let c = (await e.query(s(p).where(r("key", t)).forUpdate().descriptor))[0];
|
|
146
|
+
if (!c) throw Error("flag override disappeared during a Config change");
|
|
147
|
+
await e.update(f, String(c.id), {
|
|
148
|
+
enabled: !0,
|
|
149
|
+
rollout: 100,
|
|
150
|
+
rolloutBy: null,
|
|
151
|
+
targeting: null,
|
|
152
|
+
offVariant: null,
|
|
153
|
+
schedule: null,
|
|
154
|
+
variants: [{
|
|
155
|
+
name: "set",
|
|
156
|
+
value: a
|
|
157
|
+
}],
|
|
158
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
159
|
+
}), await T(e).record({
|
|
160
|
+
flag: t,
|
|
161
|
+
enabled: !0,
|
|
162
|
+
previousEnabled: c.enabled === !0 || c.enabled === 1,
|
|
163
|
+
actorId: o,
|
|
164
|
+
value: a,
|
|
165
|
+
previousValue: c.variants ?? null,
|
|
166
|
+
at: /* @__PURE__ */ new Date()
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}, D = async (e, t, i, a, o) => {
|
|
134
170
|
await e.transactional(async (e) => {
|
|
135
171
|
await e.insertIgnore(f, {
|
|
136
172
|
...C(x(t, i)),
|
|
@@ -151,4 +187,4 @@ var d = "_voltro_feature_flag_audit", f = "_voltro_feature_flags", p = c(f, {
|
|
|
151
187
|
});
|
|
152
188
|
};
|
|
153
189
|
//#endregion
|
|
154
|
-
export { d as FLAGS_AUDIT_TABLE, f as FLAGS_TABLE, g as FlagRegistry, T as dataStoreFlagAuditStore, S as dataStoreFlagStore, b as describeFlags, p as featureFlagsTable, m as flagAuditTable, x as flagValueToRow, y as flipFlagEnabled, h as mergeOverrides, E as persistFlagToggle, _ as registry, v as setFlagEnabled };
|
|
190
|
+
export { d as FLAGS_AUDIT_TABLE, f as FLAGS_TABLE, g as FlagRegistry, T as dataStoreFlagAuditStore, S as dataStoreFlagStore, b as describeFlags, p as featureFlagsTable, m as flagAuditTable, x as flagValueToRow, y as flipFlagEnabled, h as mergeOverrides, E as persistConfigValue, D as persistFlagToggle, _ as registry, v as setFlagEnabled };
|
package/dist/web.d.ts
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/** `TypedFlag` with the value type erased — what the plugin and the registry
|
|
2
|
+
* hold. Sound because `TypedFlag` is covariant in `A` (see the annotation). */
|
|
3
|
+
declare type AnyTypedFlag = TypedFlag<unknown>;
|
|
4
|
+
|
|
5
|
+
declare interface ConfigEntry<out A> {
|
|
6
|
+
readonly key: string;
|
|
7
|
+
readonly flag: TypedFlag<A>;
|
|
8
|
+
readonly public: boolean;
|
|
9
|
+
readonly restartRequired: 'room' | 'live';
|
|
10
|
+
readonly min: number | null;
|
|
11
|
+
readonly max: number | null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
declare interface DefinedConfig<Values extends Readonly<Record<string, unknown>> = Readonly<Record<string, unknown>>> {
|
|
15
|
+
readonly entries: {
|
|
16
|
+
readonly [Key in keyof Values]: ConfigEntry<Values[Key]>;
|
|
17
|
+
};
|
|
18
|
+
readonly keys: readonly (keyof Values & string)[];
|
|
19
|
+
readonly typedFlags: readonly AnyTypedFlag[];
|
|
20
|
+
}
|
|
21
|
+
|
|
1
22
|
/** The result of decoding an UNTRUSTED value (a DB override, a dashboard edit)
|
|
2
23
|
* against a flag's Schema. Deliberately not an exception: the caller's correct
|
|
3
24
|
* response is to keep the code-declared value and say so, not to unwind. */
|
|
@@ -149,6 +170,9 @@ declare interface TypedFlagVariant<out A> {
|
|
|
149
170
|
readonly weight?: number;
|
|
150
171
|
}
|
|
151
172
|
|
|
173
|
+
/** Explicit Config catalog; only public keys are delivered by config.mine. */
|
|
174
|
+
export declare const useConfig: <Values extends Readonly<Record<string, unknown>>, Key extends keyof Values & string>(catalog: DefinedConfig<Values>, key: Key, apiName?: string) => Values[Key];
|
|
175
|
+
|
|
152
176
|
/** `true` iff a single flag is on for the caller. */
|
|
153
177
|
export declare const useFlag: (key: string, apiName?: string) => boolean;
|
|
154
178
|
|
package/dist/web.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { BASE_NAME as e } from "./rpc.js";
|
|
2
2
|
import { typedValueOf as t } from "./define.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { captureConfigValue as n } from "./config.js";
|
|
4
|
+
import { pluginTag as r } from "@voltro/protocol";
|
|
5
|
+
import { useSubscription as i } from "@voltro/client";
|
|
5
6
|
//#region src/web.ts
|
|
6
|
-
var
|
|
7
|
-
let { data: t } =
|
|
7
|
+
var a = (t) => r(e, t), o = (e = "app") => {
|
|
8
|
+
let { data: t } = i(e, a("evaluate"), {});
|
|
8
9
|
return t ?? {};
|
|
9
|
-
},
|
|
10
|
-
let { data: t } =
|
|
10
|
+
}, s = (e, t = "app") => o(t)[e] === !0, c = (e = "app") => {
|
|
11
|
+
let { data: t } = i(e, a("variants"), {});
|
|
11
12
|
return t ?? {};
|
|
12
|
-
},
|
|
13
|
+
}, l = (e, t = "app") => c(t)[e], u = (e, n = "app") => t(e, c(n)[e.key]), d = (e, t, r = "app") => {
|
|
14
|
+
let { data: a } = i(r, "config.mine", {}), o = e.entries[t];
|
|
15
|
+
if (!o.public) throw Error("useConfig requires an explicitly public Config key");
|
|
16
|
+
let s = o.flag.decode(a?.[t]);
|
|
17
|
+
return s.ok ? s.value : n(o.flag.defaultValue);
|
|
18
|
+
};
|
|
13
19
|
//#endregion
|
|
14
|
-
export {
|
|
20
|
+
export { d as useConfig, s as useFlag, u as useFlagValue, o as useFlags, l as useVariant, c as useVariants };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/plugin-flags",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"description": "Feature flags — per-subject / per-tenant targeting, deterministic % rollouts, kill-switch. Gate mutations/queries/actions declaratively or guard in-handler; evaluate flags client-side for UI gating. Config-as-code (memory) or runtime-toggleable (postgres).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -38,7 +38,27 @@
|
|
|
38
38
|
"import": "./dist/rpc.js",
|
|
39
39
|
"default": "./dist/rpc.js"
|
|
40
40
|
},
|
|
41
|
-
"./package.json": "./package.json"
|
|
41
|
+
"./package.json": "./package.json",
|
|
42
|
+
"./config": {
|
|
43
|
+
"types": "./dist/config.d.ts",
|
|
44
|
+
"import": "./dist/config.js",
|
|
45
|
+
"default": "./dist/config.js"
|
|
46
|
+
},
|
|
47
|
+
"./config-port": {
|
|
48
|
+
"types": "./dist/config-port.d.ts",
|
|
49
|
+
"import": "./dist/config-port.js",
|
|
50
|
+
"default": "./dist/config-port.js"
|
|
51
|
+
},
|
|
52
|
+
"./config-inspect": {
|
|
53
|
+
"types": "./dist/config-inspect.d.ts",
|
|
54
|
+
"import": "./dist/config-inspect.js",
|
|
55
|
+
"default": "./dist/config-inspect.js"
|
|
56
|
+
},
|
|
57
|
+
"./config-testing": {
|
|
58
|
+
"types": "./dist/config-testing.d.ts",
|
|
59
|
+
"import": "./dist/config-testing.js",
|
|
60
|
+
"default": "./dist/config-testing.js"
|
|
61
|
+
}
|
|
42
62
|
},
|
|
43
63
|
"main": "./dist/index.js",
|
|
44
64
|
"module": "./dist/index.js",
|
|
@@ -48,10 +68,10 @@
|
|
|
48
68
|
"node": ">=24.0.0"
|
|
49
69
|
},
|
|
50
70
|
"dependencies": {
|
|
51
|
-
"@voltro/client": "0.
|
|
52
|
-
"@voltro/database": "0.
|
|
53
|
-
"@voltro/logger": "0.
|
|
54
|
-
"@voltro/protocol": "0.
|
|
71
|
+
"@voltro/client": "0.87.0",
|
|
72
|
+
"@voltro/database": "0.87.0",
|
|
73
|
+
"@voltro/logger": "0.87.0",
|
|
74
|
+
"@voltro/protocol": "0.87.0"
|
|
55
75
|
},
|
|
56
76
|
"peerDependencies": {
|
|
57
77
|
"effect": "4.0.1"
|