@flagward/react 0.2.0 → 0.2.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.
- package/README.md +145 -6
- package/dist/useFlag.d.ts.map +1 -1
- package/dist/useFlag.js +39 -17
- package/dist/useFlag.js.map +1 -1
- package/dist/useFlags.d.ts.map +1 -1
- package/dist/useFlags.js +18 -4
- package/dist/useFlags.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,27 +63,166 @@ treat any other client-side configuration.
|
|
|
63
63
|
|
|
64
64
|
## Hooks
|
|
65
65
|
|
|
66
|
-
###
|
|
66
|
+
### Which one
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
Reach for `useFlag`. One flag, one decision, one hook — it is what most
|
|
69
|
+
components need:
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
const { value, isLoading } = useFlag("new-checkout");
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`useFlags` earns its place in three cases:
|
|
76
|
+
|
|
77
|
+
- **The keys are not known where you write the code** — a debug panel, an admin
|
|
78
|
+
view, anything that iterates.
|
|
79
|
+
- **You need a flag where a hook cannot go** — inside an event handler, a
|
|
80
|
+
callback, a conditional branch. Hooks cannot be conditional; `getFlag` can.
|
|
81
|
+
- **A component reads several flags** and one call reads better than five.
|
|
82
|
+
|
|
83
|
+
### `useFlag(key, context?)`
|
|
84
|
+
|
|
85
|
+
Evaluates a single flag.
|
|
69
86
|
|
|
70
87
|
```tsx
|
|
71
88
|
const { value, isLoading, error } = useFlag("new-dashboard");
|
|
72
89
|
```
|
|
73
90
|
|
|
74
91
|
Returns:
|
|
75
|
-
- `value`: `boolean |
|
|
92
|
+
- `value`: `boolean | undefined` — `undefined` while loading, and for a key
|
|
93
|
+
this environment does not have
|
|
76
94
|
- `isLoading`: `boolean`
|
|
77
95
|
- `error`: `Error | null`
|
|
78
96
|
|
|
97
|
+
The optional second argument adds to the provider's context for this call
|
|
98
|
+
only. See "Where context comes from" below, which is the part that surprises
|
|
99
|
+
people.
|
|
100
|
+
|
|
79
101
|
### `useFlags()`
|
|
80
102
|
|
|
81
|
-
|
|
103
|
+
The whole environment at once.
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
const { flags, isLoading, error, getFlag } = useFlags();
|
|
107
|
+
|
|
108
|
+
flags; // { "new-checkout": true, ... }
|
|
109
|
+
getFlag("show-banner"); // one flag, the provider's context
|
|
110
|
+
getFlag("show-banner", { plan: "pro" }); // one flag, plus this context
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`getFlag` is a plain function, so it can be called anywhere — including places
|
|
114
|
+
a hook cannot go.
|
|
115
|
+
|
|
116
|
+
### Where context comes from
|
|
117
|
+
|
|
118
|
+
Targeting rules are evaluated against a context, and there are two places it
|
|
119
|
+
can come from. They are not interchangeable:
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
<FlagwardProvider context={{ plan: "free" }}> // who the user is
|
|
123
|
+
useFlag("beta", { plan: "pro" }) // just this call
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
A context passed to `useFlag` belongs to **that call**. It is not published
|
|
127
|
+
anywhere: another component cannot see it, and `useFlags().flags` resolves its
|
|
128
|
+
map against the provider's context alone. So this is not a contradiction —
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
const { value } = useFlag("beta", { plan: "pro" }); // true
|
|
132
|
+
const { flags } = useFlags(); // flags.beta === false
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
— it is two questions with two answers. The call was told `"pro"`; the map was
|
|
136
|
+
not. Deliberately: if a context passed in one component reached another
|
|
137
|
+
component's hook, you would have an invisible channel between parts of an
|
|
138
|
+
application that share nothing.
|
|
139
|
+
|
|
140
|
+
**So put the user in the provider.** Plan, country, id, locale — whatever your
|
|
141
|
+
rules target — belongs there, where one answer applies everywhere and follows
|
|
142
|
+
the user through signing in and changing plan. Reach for the per-call context
|
|
143
|
+
when what you are evaluating is *not* the current user:
|
|
82
144
|
|
|
83
145
|
```tsx
|
|
84
|
-
|
|
146
|
+
// A list of users. The flag is asked about each row, not about the viewer.
|
|
147
|
+
users.map((u) => <Row key={u.id} badge={getFlag("premium-badge", { plan: u.plan })} />)
|
|
148
|
+
```
|
|
85
149
|
|
|
86
|
-
|
|
150
|
+
### Putting it together
|
|
151
|
+
|
|
152
|
+
The user lives in the provider, once:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
// providers.tsx
|
|
156
|
+
import { FlagwardProvider } from "@flagward/react";
|
|
157
|
+
|
|
158
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
159
|
+
const { user } = useAuth();
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<FlagwardProvider
|
|
163
|
+
apiKey={import.meta.env.VITE_FLAGWARD_API_KEY}
|
|
164
|
+
host="https://flags.example.com"
|
|
165
|
+
context={{ plan: user.plan, country: user.country, id: user.id }}
|
|
166
|
+
>
|
|
167
|
+
{children}
|
|
168
|
+
</FlagwardProvider>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Signing in or changing plan re-renders this, and every flag in the application
|
|
174
|
+
follows — you do not tell each component separately.
|
|
175
|
+
|
|
176
|
+
One decision, one flag:
|
|
177
|
+
|
|
178
|
+
```tsx
|
|
179
|
+
// Checkout.tsx
|
|
180
|
+
function Checkout() {
|
|
181
|
+
const { value: newCheckout, isLoading } = useFlag("new-checkout");
|
|
182
|
+
|
|
183
|
+
if (isLoading) return <LegacyCheckout />;
|
|
184
|
+
|
|
185
|
+
return newCheckout ? <NewCheckout /> : <LegacyCheckout />;
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
A flag inside a handler, where a hook cannot go:
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
// CheckoutForm.tsx
|
|
193
|
+
function CheckoutForm() {
|
|
194
|
+
const { getFlag } = useFlags();
|
|
195
|
+
|
|
196
|
+
const handleSubmit = (data: FormData) => {
|
|
197
|
+
if (getFlag("strict-validation") && !isComplete(data)) {
|
|
198
|
+
return setError("Every field is required.");
|
|
199
|
+
}
|
|
200
|
+
submit(data);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
And the one case for a per-call context — the flag is about each row, not about
|
|
208
|
+
whoever is looking:
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
// UserTable.tsx
|
|
212
|
+
function UserTable({ users }: { users: User[] }) {
|
|
213
|
+
const { getFlag } = useFlags();
|
|
214
|
+
|
|
215
|
+
return (
|
|
216
|
+
<tbody>
|
|
217
|
+
{users.map((u) => (
|
|
218
|
+
<tr key={u.id}>
|
|
219
|
+
<td>{u.name}</td>
|
|
220
|
+
<td>{getFlag("premium-badge", { plan: u.plan }) ? "★" : null}</td>
|
|
221
|
+
</tr>
|
|
222
|
+
))}
|
|
223
|
+
</tbody>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
87
226
|
```
|
|
88
227
|
|
|
89
228
|
## Provider
|
package/dist/useFlag.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFlag.d.ts","sourceRoot":"","sources":["../src/useFlag.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"useFlag.d.ts","sourceRoot":"","sources":["../src/useFlag.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,aAAa,CA+D7E"}
|
package/dist/useFlag.js
CHANGED
|
@@ -1,26 +1,48 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
1
|
+
import { useContext, useEffect, useMemo } from "react";
|
|
2
2
|
import { FlagwardContext } from "./context.js";
|
|
3
3
|
import { createLogger, evaluateFlag } from "@flagward/core";
|
|
4
4
|
export function useFlag(key, flagContext) {
|
|
5
5
|
const context = useContext(FlagwardContext);
|
|
6
|
-
|
|
7
|
-
//
|
|
6
|
+
// Memoised so the effect below has a stable dependency. Without a client
|
|
7
|
+
// this builds a fresh logger, and a new object every render would re-run the
|
|
8
|
+
// effect on every render for no reason.
|
|
9
|
+
const logger = useMemo(() => context.client?.logger ?? createLogger(), [context.client]);
|
|
8
10
|
const mergedContext = { ...context.context, ...flagContext };
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Resolves the flag, and does nothing else.
|
|
13
|
+
*
|
|
14
|
+
* Evaluated against the data this render was produced from, so the value
|
|
15
|
+
* shown and the update that caused it can never disagree.
|
|
16
|
+
*/
|
|
17
|
+
const value = !context.client || context.isLoading
|
|
18
|
+
? undefined
|
|
19
|
+
: evaluateFlag(context.flagsData[key], mergedContext);
|
|
20
|
+
/**
|
|
21
|
+
* Reports what the caller cannot see, after the render rather than during it.
|
|
22
|
+
*
|
|
23
|
+
* Rendering must be a pure calculation. React re-renders on its own schedule
|
|
24
|
+
* -- a parent updating, an unrelated state change, StrictMode running the
|
|
25
|
+
* render twice on purpose to expose exactly this -- so a render that writes
|
|
26
|
+
* to the console produces a number of warnings that reflects React's
|
|
27
|
+
* scheduling rather than anything that went wrong. The output was bounded
|
|
28
|
+
* only because the logger deduplicates.
|
|
29
|
+
*
|
|
30
|
+
* The unknown-key warning waits for loading to finish. Reporting earlier
|
|
31
|
+
* would name every flag on every page load, when the only thing wrong is
|
|
32
|
+
* that the answer has not arrived yet.
|
|
33
|
+
*/
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!context.client) {
|
|
36
|
+
logger.error("no-provider", `useFlag("${key}") was called outside FlagwardProvider, so it can only ` +
|
|
37
|
+
"return undefined. Wrap the tree in <FlagwardProvider>.");
|
|
38
|
+
return;
|
|
22
39
|
}
|
|
23
|
-
|
|
40
|
+
if (context.isLoading || value !== undefined)
|
|
41
|
+
return;
|
|
42
|
+
logger.warn(`unknown-flag:${key}`, `Flag "${key}" is not in this environment, so it reads as undefined. ` +
|
|
43
|
+
"Check the key, and that the flag exists in the environment this " +
|
|
44
|
+
"API key belongs to.");
|
|
45
|
+
}, [context.client, context.isLoading, value, key, logger]);
|
|
24
46
|
return {
|
|
25
47
|
value,
|
|
26
48
|
isLoading: context.isLoading,
|
package/dist/useFlag.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFlag.js","sourceRoot":"","sources":["../src/useFlag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useFlag.js","sourceRoot":"","sources":["../src/useFlag.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAU5D,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,WAAyB;IAC5D,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,yEAAyE;IACzE,6EAA6E;IAC7E,wCAAwC;IACxC,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,YAAY,EAAE,EAC9C,CAAC,OAAO,CAAC,MAAM,CAAC,CACjB,CAAC;IAEF,MAAM,aAAa,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC;IAE7D;;;;;OAKG;IACH,MAAM,KAAK,GACT,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,SAAS;QAClC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;IAE1D;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CACV,aAAa,EACb,YAAY,GAAG,yDAAyD;gBACtE,wDAAwD,CAC3D,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,OAAO,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO;QAErD,MAAM,CAAC,IAAI,CACT,gBAAgB,GAAG,EAAE,EACrB,SAAS,GAAG,0DAA0D;YACpE,kEAAkE;YAClE,qBAAqB,CACxB,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAE5D,OAAO;QACL,KAAK;QACL,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC"}
|
package/dist/useFlags.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFlags.d.ts","sourceRoot":"","sources":["../src/useFlags.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,GAAG,SAAS,CAAC;CAC1E;AAED,wBAAgB,QAAQ,IAAI,cAAc,
|
|
1
|
+
{"version":3,"file":"useFlags.d.ts","sourceRoot":"","sources":["../src/useFlags.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,GAAG,SAAS,CAAC;CAC1E;AAED,wBAAgB,QAAQ,IAAI,cAAc,CAoDzC"}
|
package/dist/useFlags.js
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
1
|
+
import { useContext, useEffect, useMemo } from "react";
|
|
2
2
|
import { FlagwardContext } from "./context.js";
|
|
3
3
|
import { createLogger, evaluateFlag, toFlagMap } from "@flagward/core";
|
|
4
4
|
export function useFlags() {
|
|
5
5
|
const context = useContext(FlagwardContext);
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
// Memoised so the effect below has a stable dependency. See useFlag.
|
|
7
|
+
const logger = useMemo(() => context.client?.logger ?? createLogger(), [context.client]);
|
|
8
|
+
// Reported after the render, not during it: rendering must be a pure
|
|
9
|
+
// calculation, and React runs it as often as it likes.
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (context.client)
|
|
12
|
+
return;
|
|
8
13
|
logger.error("no-provider", "useFlags() was called outside FlagwardProvider, so it can only return " +
|
|
9
14
|
"an empty set. Wrap the tree in <FlagwardProvider>.");
|
|
10
|
-
}
|
|
15
|
+
}, [context.client, logger]);
|
|
16
|
+
/**
|
|
17
|
+
* Resolves one flag, and reports a key this environment does not have.
|
|
18
|
+
*
|
|
19
|
+
* Reporting inline here, where the render moved it into an effect, is not an
|
|
20
|
+
* inconsistency. This is a function the caller invokes: it runs when asked
|
|
21
|
+
* to, exactly as often as it is asked, so a warning is a direct answer to a
|
|
22
|
+
* direct question. A render runs on React's schedule instead, which is why
|
|
23
|
+
* the reporting had to leave it.
|
|
24
|
+
*/
|
|
11
25
|
const getFlag = (key, flagContext) => {
|
|
12
26
|
const mergedContext = { ...context.context, ...flagContext };
|
|
13
27
|
const value = evaluateFlag(context.flagsData[key], mergedContext);
|
package/dist/useFlags.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFlags.js","sourceRoot":"","sources":["../src/useFlags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useFlags.js","sourceRoot":"","sources":["../src/useFlags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAUvE,MAAM,UAAU,QAAQ;IACtB,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,qEAAqE;IACrE,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,IAAI,YAAY,EAAE,EAC9C,CAAC,OAAO,CAAC,MAAM,CAAC,CACjB,CAAC;IAEF,qEAAqE;IACrE,uDAAuD;IACvD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,CAAC,MAAM;YAAE,OAAO;QAE3B,MAAM,CAAC,KAAK,CACV,aAAa,EACb,wEAAwE;YACtE,oDAAoD,CACvD,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAE7B;;;;;;;;OAQG;IACH,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,WAAyB,EAAuB,EAAE;QAC9E,MAAM,aAAa,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC;QAC7D,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;QAElE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CACT,gBAAgB,GAAG,EAAE,EACrB,SAAS,GAAG,0DAA0D;gBACpE,kEAAkE;gBAClE,qBAAqB,CACxB,CAAC;QACJ,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC;QACpD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO;KACR,CAAC;AACJ,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* GENERATED by scripts/sync-version.mjs from package.json. Do not edit: the
|
|
5
5
|
* next build overwrites it, and a test fails if the two disagree.
|
|
6
6
|
*/
|
|
7
|
-
export declare const SDK_VERSION = "0.2.
|
|
7
|
+
export declare const SDK_VERSION = "0.2.1";
|
|
8
8
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED