@guidelytech/flags 0.0.0-stage → 0.7.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Guidely
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,135 @@
1
- # Temporary Holding Version
1
+ # @guidelytech/flags
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Guidely feature flags, remote config and experiments for TypeScript. One client for browsers,
4
+ Node.js ≥ 18, Next.js (server and edge), Deno, Bun and React Native; no runtime dependencies.
5
+
6
+ If you already use a Guidely SDK (`@guidelytech/react`, `nextjs`, `react-native`, `svelte`,
7
+ `sveltekit`, `sdk-core` or the script tag), flags are built in: `guidely.flags`, `useFlag()`,
8
+ `flag()`… with identity, page and device attributes filled in for you. Use this package directly
9
+ for servers, edge functions and flags-only apps.
10
+
11
+ ```bash
12
+ pnpm add @guidelytech/flags
13
+ ```
14
+
15
+ ## Keys
16
+
17
+ * **Public key** `pk_…` — the environment key you already use as `projectId` for tracking. Works
18
+ everywhere, with no other configuration.
19
+ * **Secret key** `gly_sk_…` (scope `flags:read`, servers only) — also needs `environment`. Gets
20
+ server-only flags, and works when the environment hides its rules from public keys.
21
+
22
+ ## Browser
23
+
24
+ ```ts
25
+ import { createFlagsClient } from "@guidelytech/flags";
26
+
27
+ const flags = createFlagsClient({
28
+ sdkKey: "pk_prod_…",
29
+ apiUrl: "https://guidelytech.com",
30
+ attributes: { id: user.id, plan: user.plan, account: { id: org.id } },
31
+ });
32
+
33
+ await flags.ready();
34
+ if (flags.isEnabled("new-checkout")) showNewCheckout();
35
+ const color = flags.getString("checkout-button-color", "blue");
36
+ flags.subscribe(() => render()); // payload, attribute or override changes
37
+ flags.updateAttributes({ plan: "enterprise" });
38
+ ```
39
+
40
+ The last payload is kept in `localStorage`, so returning visitors get flags instantly and offline.
41
+
42
+ ## Node.js / server
43
+
44
+ One client per process; evaluate per request with `forUser()` (it never changes the client):
45
+
46
+ ```ts
47
+ import { createFlagsClient } from "@guidelytech/flags";
48
+
49
+ export const flags = createFlagsClient({ sdkKey: process.env.GUIDELY_SDK_KEY!, environment: "production" });
50
+
51
+ app.get("/checkout", async (req, res) => {
52
+ await flags.ready(); // resolves once, after the first download (or failure)
53
+ const f = flags.forUser({ id: req.user.id, plan: req.user.plan });
54
+ res.render("checkout", { newCheckout: f.isEnabled("new-checkout"), limits: f.getJson("limits", {}) });
55
+ });
56
+ ```
57
+
58
+ ## Next.js
59
+
60
+ Use `@guidelytech/nextjs/server` (`getFlags()`, `getFlagsBootstrap()`): it keeps one client across
61
+ requests and hot reloads and bypasses the Next.js fetch cache. Pass `getFlagsBootstrap()` to the
62
+ browser provider to render the same values on the server and the client.
63
+
64
+ ## Edge runtimes and serverless
65
+
66
+ Instances are short-lived, so don't poll — refresh on read once the cache is stale:
67
+
68
+ ```ts
69
+ const flags = createFlagsClient({ sdkKey: "pk_prod_…", pollingMode: "lazy", cacheTtlSeconds: 30 });
70
+ ```
71
+
72
+ ## API
73
+
74
+ | | |
75
+ |---|---|
76
+ | `ready()` / `isReady()` | First load settled (bootstrap, network success or failure). Never rejects. |
77
+ | `isEnabled(key, fallback = false)` | Boolean flags only: any other value gives `fallback`. |
78
+ | `getValue(key, fallback)` | Value, or `fallback` when missing, null or of another JSON type. |
79
+ | `getString` / `getNumber` / `getBoolean` / `getJson` | Typed getters with the same rule. |
80
+ | `getDetails(key, fallback)` | Value plus `reason`, `ruleId`, `variationId`, `experiment`, `usedFallback`. |
81
+ | `getAll()` | Every flag's value (records no exposures). |
82
+ | `forUser(attributes)` | Getters for other attributes (merged over the client's). |
83
+ | `setAttributes` / `updateAttributes` / `getAttributes` | Replace / merge / read the attributes. |
84
+ | `setOverrides(map \| null)` | Local values (see `overrideBehaviour`). |
85
+ | `setOffline(bool)` / `refresh()` | Pause network activity / fetch now. |
86
+ | `getPayload()` | The payload (or remote results) to bootstrap a browser from server rendering. |
87
+ | `subscribe(listener)` | Change notifications; returns `unsubscribe` (works with `useSyncExternalStore`). |
88
+ | `flush()` / `destroy()` | Send usage now / stop timers and streams. |
89
+
90
+ Getters never throw and never block: before flags load (or if Guidely is unreachable) they return
91
+ your fallback, and afterwards the last good payload.
92
+
93
+ ### Options
94
+
95
+ | Option | Default | |
96
+ |---|---|---|
97
+ | `sdkKey` (alias `projectId`) | — | `pk_…` or `gly_sk_…`. |
98
+ | `apiUrl` | `https://guidelytech.com` | Your Guidely URL. |
99
+ | `environment` | — | Required with `gly_sk_` keys. |
100
+ | `attributes` | `{}` | Default attributes. |
101
+ | `pollingMode` | `auto` | `auto` (every `pollIntervalSeconds`, default 60), `lazy` (on read after `cacheTtlSeconds`), `manual` (`refresh()` only), `stream` (server-sent events, polling while disconnected). |
102
+ | `payload` / `remoteResults` | — | Bootstrap: used immediately (`ready` at once). |
103
+ | `remoteEval` | `false` | Evaluate on the server (`POST /flags/evaluate`) for environments that hide their rules. Switched on automatically when a public key gets `remote_evaluation_required`. Re-evaluates (debounced) when attributes change; results are cached per attribute set. |
104
+ | `decryptionKey` | — | For encrypted payloads (AES-256-GCM via WebCrypto). |
105
+ | `overrides` / `overrideBehaviour` | — / `localOverRemote` | `localOnly` (never fetch), `localOverRemote` (overrides win), `remoteOverLocal` (only for flags missing remotely). |
106
+ | `enableUrlOverrides` | `false` | Browser QA: `?guidely_flags=new-checkout:true,checkout-button-color:"green"`. |
107
+ | `stickyBucketService` | — | `InMemoryStickyBucketStore` / `LocalStorageStickyBucketStore`: users keep their experiment variation. |
108
+ | `storage` | `localStorage` in browsers | Any `getItem`/`setItem` store, sync or async (AsyncStorage). `false` disables. |
109
+ | `trackingCallback(experiment, result)` | — | Once per (experiment, user, variation): send exposures to your analytics. |
110
+ | `trackExposures` | `true` unless `trackingCallback` | Send exposures to Guidely for experiment results. |
111
+ | `reportUsage` | `true` | Aggregated evaluation counts, at most every 60 s (`sendBeacon` on page hide). |
112
+ | `onReady`, `onChange`, `onFlagEvaluated`, `onError` | — | Hooks. |
113
+ | `offline`, `fetch`, `logger`, `now` | — | Start offline; custom fetch; `null` silences logs; clock for tests. |
114
+
115
+ `createStaticFlags({ payload, attributes })` gives the same getters over a payload with no network
116
+ or tracking — framework bindings use it to server-render and hydrate.
117
+
118
+ ## CLI
119
+
120
+ ```bash
121
+ # In CI on your main branch: upload where each flag is used in code (shown on the flag's page).
122
+ npx guidely-flags code-refs --key "$GUIDELY_API_KEY" --environment production --repo acme/web
123
+
124
+ # Debug an evaluation.
125
+ npx guidely-flags evaluate --key pk_prod_… --flag new-checkout --attributes '{"id":"u1","plan":"pro"}'
126
+ ```
127
+
128
+ `code-refs` needs a `gly_sk_` key with `flags:read` and `flags:code-refs`. It scans files from
129
+ `git ls-files` (or a walk skipping `node_modules`, `dist`, `build`, `vendor`…) under 1 MB for flag
130
+ keys written as quoted string literals, and uploads `{ repo, branch, commit, refs }`. Branch and
131
+ commit default to the current git checkout (or `GITHUB_REF_NAME` / `GITHUB_SHA`). `--dry-run`
132
+ prints the references instead. `guidely-flags --help` lists every option.
133
+
134
+ The evaluation semantics are specified in
135
+ [docs/feature-flags-spec.md](https://github.com/parmarg/Guidely/blob/main/docs/feature-flags-spec.md).