@vexillo/react-sdk 1.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,92 @@
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 src_exports = {};
22
+ __export(src_exports, {
23
+ VexilloProvider: () => VexilloProvider,
24
+ useFlag: () => useFlag
25
+ });
26
+ module.exports = __toCommonJS(src_exports);
27
+
28
+ // src/provider.tsx
29
+ var import_react = require("react");
30
+ var import_jsx_runtime = require("react/jsx-runtime");
31
+ var VexilloContext = (0, import_react.createContext)(null);
32
+ function VexilloProvider({
33
+ baseUrl,
34
+ apiKey,
35
+ fallbacks = {},
36
+ children
37
+ }) {
38
+ const [flags, setFlags] = (0, import_react.useState)(null);
39
+ const [error, setError] = (0, import_react.useState)(null);
40
+ (0, import_react.useEffect)(() => {
41
+ let cancelled = false;
42
+ fetch(`${baseUrl}/api/flags`, {
43
+ headers: { Authorization: `Bearer ${apiKey}` }
44
+ }).then((res) => {
45
+ if (!res.ok) {
46
+ throw new Error(
47
+ `Vexillo: API responded with status ${res.status} ${res.statusText}`
48
+ );
49
+ }
50
+ return res.json();
51
+ }).then((data) => {
52
+ if (cancelled) return;
53
+ const map = {};
54
+ for (const f of data.flags) {
55
+ map[f.key] = f.enabled;
56
+ }
57
+ setFlags(map);
58
+ }).catch((err) => {
59
+ if (cancelled) return;
60
+ setError(
61
+ err instanceof Error ? err : new Error(`Vexillo: unexpected error \u2014 ${String(err)}`)
62
+ );
63
+ });
64
+ return () => {
65
+ cancelled = true;
66
+ };
67
+ }, [apiKey, baseUrl]);
68
+ if (error) throw error;
69
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VexilloContext.Provider, { value: { flags, fallbacks }, children });
70
+ }
71
+ function useVexilloContext() {
72
+ const ctx = (0, import_react.useContext)(VexilloContext);
73
+ if (ctx === null) {
74
+ throw new Error("useFlag must be called inside a <VexilloProvider>.");
75
+ }
76
+ return ctx;
77
+ }
78
+
79
+ // src/use-flag.ts
80
+ function useFlag(key) {
81
+ var _a;
82
+ const { flags, fallbacks } = useVexilloContext();
83
+ if (flags !== null && key in flags) {
84
+ return flags[key];
85
+ }
86
+ return (_a = fallbacks[key]) != null ? _a : false;
87
+ }
88
+ // Annotate the CommonJS export names for ESM import in node:
89
+ 0 && (module.exports = {
90
+ VexilloProvider,
91
+ useFlag
92
+ });
@@ -0,0 +1,27 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ interface VexilloProviderProps {
4
+ /** Base URL of your Vexillo deployment (e.g. "https://vexillo.example.com") */
5
+ baseUrl: string;
6
+ /** SDK API key for the target environment */
7
+ apiKey: string;
8
+ /** Environment slug — stored in context for consumer reference */
9
+ environment: string;
10
+ /** Flag values used before the fetch resolves and for unknown keys */
11
+ fallbacks?: Record<string, boolean>;
12
+ children: ReactNode;
13
+ }
14
+ declare function VexilloProvider({ baseUrl, apiKey, fallbacks, children, }: VexilloProviderProps): ReactNode;
15
+
16
+ /**
17
+ * Returns the current boolean value for a feature flag key.
18
+ *
19
+ * - Before the provider's fetch resolves (including SSR), returns the value
20
+ * from `fallbacks`, or `false` if the key is absent.
21
+ * - After the fetch resolves, returns the live value from the API, falling
22
+ * back to `fallbacks[key] ?? false` for keys not present in the response.
23
+ * - Throws if called outside a `<VexilloProvider>`.
24
+ */
25
+ declare function useFlag(key: string): boolean;
26
+
27
+ export { VexilloProvider, type VexilloProviderProps, useFlag };
@@ -0,0 +1,27 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ interface VexilloProviderProps {
4
+ /** Base URL of your Vexillo deployment (e.g. "https://vexillo.example.com") */
5
+ baseUrl: string;
6
+ /** SDK API key for the target environment */
7
+ apiKey: string;
8
+ /** Environment slug — stored in context for consumer reference */
9
+ environment: string;
10
+ /** Flag values used before the fetch resolves and for unknown keys */
11
+ fallbacks?: Record<string, boolean>;
12
+ children: ReactNode;
13
+ }
14
+ declare function VexilloProvider({ baseUrl, apiKey, fallbacks, children, }: VexilloProviderProps): ReactNode;
15
+
16
+ /**
17
+ * Returns the current boolean value for a feature flag key.
18
+ *
19
+ * - Before the provider's fetch resolves (including SSR), returns the value
20
+ * from `fallbacks`, or `false` if the key is absent.
21
+ * - After the fetch resolves, returns the live value from the API, falling
22
+ * back to `fallbacks[key] ?? false` for keys not present in the response.
23
+ * - Throws if called outside a `<VexilloProvider>`.
24
+ */
25
+ declare function useFlag(key: string): boolean;
26
+
27
+ export { VexilloProvider, type VexilloProviderProps, useFlag };
package/dist/index.js ADDED
@@ -0,0 +1,69 @@
1
+ // src/provider.tsx
2
+ import {
3
+ createContext,
4
+ useContext,
5
+ useEffect,
6
+ useState
7
+ } from "react";
8
+ import { jsx } from "react/jsx-runtime";
9
+ var VexilloContext = createContext(null);
10
+ function VexilloProvider({
11
+ baseUrl,
12
+ apiKey,
13
+ fallbacks = {},
14
+ children
15
+ }) {
16
+ const [flags, setFlags] = useState(null);
17
+ const [error, setError] = useState(null);
18
+ useEffect(() => {
19
+ let cancelled = false;
20
+ fetch(`${baseUrl}/api/flags`, {
21
+ headers: { Authorization: `Bearer ${apiKey}` }
22
+ }).then((res) => {
23
+ if (!res.ok) {
24
+ throw new Error(
25
+ `Vexillo: API responded with status ${res.status} ${res.statusText}`
26
+ );
27
+ }
28
+ return res.json();
29
+ }).then((data) => {
30
+ if (cancelled) return;
31
+ const map = {};
32
+ for (const f of data.flags) {
33
+ map[f.key] = f.enabled;
34
+ }
35
+ setFlags(map);
36
+ }).catch((err) => {
37
+ if (cancelled) return;
38
+ setError(
39
+ err instanceof Error ? err : new Error(`Vexillo: unexpected error \u2014 ${String(err)}`)
40
+ );
41
+ });
42
+ return () => {
43
+ cancelled = true;
44
+ };
45
+ }, [apiKey, baseUrl]);
46
+ if (error) throw error;
47
+ return /* @__PURE__ */ jsx(VexilloContext.Provider, { value: { flags, fallbacks }, children });
48
+ }
49
+ function useVexilloContext() {
50
+ const ctx = useContext(VexilloContext);
51
+ if (ctx === null) {
52
+ throw new Error("useFlag must be called inside a <VexilloProvider>.");
53
+ }
54
+ return ctx;
55
+ }
56
+
57
+ // src/use-flag.ts
58
+ function useFlag(key) {
59
+ var _a;
60
+ const { flags, fallbacks } = useVexilloContext();
61
+ if (flags !== null && key in flags) {
62
+ return flags[key];
63
+ }
64
+ return (_a = fallbacks[key]) != null ? _a : false;
65
+ }
66
+ export {
67
+ VexilloProvider,
68
+ useFlag
69
+ };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@vexillo/react-sdk",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org",
7
+ "access": "public"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "peerDependencies": {
20
+ "react": "^18 || ^19",
21
+ "react-dom": "^18 || ^19"
22
+ },
23
+ "devDependencies": {
24
+ "@testing-library/react": "^16",
25
+ "@types/react": "^19",
26
+ "@types/react-dom": "^19",
27
+ "jsdom": "^26",
28
+ "react": "^19",
29
+ "react-dom": "^19",
30
+ "tsup": "^8",
31
+ "typescript": "^5",
32
+ "vitest": "^3"
33
+ },
34
+ "scripts": {
35
+ "build": "tsup",
36
+ "dev": "tsup --watch",
37
+ "lint": "tsc --noEmit",
38
+ "test": "vitest run"
39
+ }
40
+ }