@sdxc/flags-engine 0.0.0-pre.1

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,117 @@
1
+ /**
2
+ * The suite that says what a flag store is, registered as Vitest tests against
3
+ * whatever the caller constructs. Every store runs it, the one an application
4
+ * writes against its own tables included, which is what makes them substitutes.
5
+ *
6
+ * @author [Sergio Xalambrí](https://sergiodxa.com)
7
+ * @copyright Sergio Xalambrí 2026
8
+ */
9
+ import { isSuccess, unwrap } from "@sdxc/result";
10
+ import { describe, expect, test } from "vitest";
11
+ import { FlagStoreError } from "../store/index.js";
12
+ /** A set carrying every field a store round trips, so each one is asserted on. */
13
+ const FLAG_SET = {
14
+ flags: {
15
+ "new-checkout": {
16
+ variants: { on: true, off: false },
17
+ defaultVariant: "off",
18
+ targeting: [{ when: { op: "segment", name: "internal" }, serve: "on" }],
19
+ },
20
+ },
21
+ segments: { internal: { op: "endsWith", field: "email", value: "@example.com" } },
22
+ version: "17",
23
+ };
24
+ /** A second set, so a write can be asserted to replace rather than to merge. */
25
+ const OTHER_FLAG_SET = {
26
+ flags: { "welcome-banner": { variants: { on: true, off: false } } },
27
+ version: "18",
28
+ };
29
+ /** Text no store wrote, which is how a set arrives unreadable in practice. */
30
+ const NOT_JSON = "{oops";
31
+ /** JSON holding something other than a set, the other way a value goes wrong. */
32
+ const NOT_AN_OBJECT = "[]";
33
+ /**
34
+ * Registers the suite every flag store has to pass.
35
+ *
36
+ * @param options The store under test, and the capabilities it has beyond reading.
37
+ * @example conformance({ name: "worker-kv", create: () => new WorkerKVFlagStore(env.FLAGS), seed })
38
+ */
39
+ export function conformance({ name, create, seed, write, writeText, }) {
40
+ /** The error a read answered with, asserting that it answered with one. */
41
+ let errorOf = (result) => {
42
+ if (isSuccess(result))
43
+ throw new Error("expected a failure, got a success");
44
+ return result.error;
45
+ };
46
+ describe(`${name} conformance`, () => {
47
+ test("reads a store holding nothing as an empty set", async () => {
48
+ let store = await create();
49
+ expect(unwrap(await store.read()).flags).toStrictEqual({});
50
+ });
51
+ test("reads back the flags and segments it holds", async () => {
52
+ let store = await create();
53
+ await seed(store, FLAG_SET);
54
+ let set = unwrap(await store.read());
55
+ expect(set.flags).toStrictEqual(FLAG_SET.flags);
56
+ expect(set.segments).toStrictEqual(FLAG_SET.segments);
57
+ });
58
+ test("carries the version the set was stored with", async () => {
59
+ let store = await create();
60
+ await seed(store, FLAG_SET);
61
+ expect(unwrap(await store.read()).version).toBe(FLAG_SET.version);
62
+ });
63
+ test("answers every read with the same set", async () => {
64
+ let store = await create();
65
+ await seed(store, FLAG_SET);
66
+ let first = unwrap(await store.read());
67
+ let second = unwrap(await store.read());
68
+ expect(second).toStrictEqual(first);
69
+ });
70
+ test("hands over a set the caller owns", async () => {
71
+ let store = await create();
72
+ await seed(store, FLAG_SET);
73
+ let read = unwrap(await store.read());
74
+ read.flags["injected"] = { variants: { on: true } };
75
+ expect(unwrap(await store.read()).flags).toStrictEqual(FLAG_SET.flags);
76
+ });
77
+ if (write !== undefined) {
78
+ test("reads back exactly what it wrote", async () => {
79
+ let store = await create();
80
+ await write(store, FLAG_SET);
81
+ expect(unwrap(await store.read())).toStrictEqual(FLAG_SET);
82
+ });
83
+ test("replaces the set it was already holding", async () => {
84
+ let store = await create();
85
+ await seed(store, FLAG_SET);
86
+ await write(store, OTHER_FLAG_SET);
87
+ expect(unwrap(await store.read())).toStrictEqual(OTHER_FLAG_SET);
88
+ });
89
+ test("reads an empty set back once it writes one", async () => {
90
+ let store = await create();
91
+ await seed(store, FLAG_SET);
92
+ await write(store, { flags: {} });
93
+ expect(unwrap(await store.read()).flags).toStrictEqual({});
94
+ });
95
+ }
96
+ if (writeText === undefined)
97
+ return;
98
+ test("reports a stored value that is not JSON", async () => {
99
+ let store = await create();
100
+ await writeText(store, NOT_JSON);
101
+ let error = errorOf(await store.read());
102
+ expect(error).toBeInstanceOf(FlagStoreError);
103
+ expect(error.code).toBe("invalid_value");
104
+ });
105
+ test("reports stored JSON that is not a set", async () => {
106
+ let store = await create();
107
+ await writeText(store, NOT_AN_OBJECT);
108
+ expect(errorOf(await store.read()).code).toBe("invalid_value");
109
+ });
110
+ test("reads normally again once the value is replaced", async () => {
111
+ let store = await create();
112
+ await writeText(store, NOT_JSON);
113
+ await seed(store, FLAG_SET);
114
+ expect(unwrap(await store.read()).flags).toStrictEqual(FLAG_SET.flags);
115
+ });
116
+ });
117
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@sdxc/flags-engine",
3
+ "version": "0.0.0-pre.1",
4
+ "description": "Flag evaluation engine: typed targeting rules, percentage splits and pluggable stores",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": "./dist/index.js",
9
+ "./store": "./dist/store/index.js",
10
+ "./store/memory": "./dist/store/memory.js",
11
+ "./store/worker-kv": "./dist/store/worker-kv.js",
12
+ "./conformance": "./dist/testing/conformance.js",
13
+ "./provider": "./dist/provider/index.js"
14
+ },
15
+ "dependencies": {
16
+ "@sdxc/duration": "2026.9.11",
17
+ "@sdxc/flags": "0.0.0-pre.1",
18
+ "@sdxc/result": "2026.9.11",
19
+ "@sdxc/semver": "0.0.0-pre.1",
20
+ "@sdxc/types": "2026.9.11",
21
+ "remix": "3.0.0-rc.2"
22
+ },
23
+ "peerDependencies": {
24
+ "vitest": "^4.0.0"
25
+ },
26
+ "peerDependenciesMeta": {
27
+ "vitest": {
28
+ "optional": true
29
+ }
30
+ },
31
+ "gitHead": "d56f75a79171aab3be101d8fa624d51972cd6028",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/sergiodxa/monorepo.git",
38
+ "directory": "packages/flags-engine"
39
+ }
40
+ }