@flaggly/sdk 0.0.1 → 0.0.4
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.d.mts +73 -9
- package/dist/index.d.ts +73 -9
- package/dist/index.js +57 -5
- package/dist/index.mjs +57 -5
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -22,7 +22,9 @@ type FlagInput = {
|
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
type FlagValue<FR extends FlagConfig = FlagConfig> = FR extends {
|
|
25
|
-
type: "variant"
|
|
25
|
+
type: "variant";
|
|
26
|
+
} ? FR["result"] : FR extends {
|
|
27
|
+
type: "payload";
|
|
26
28
|
} ? FR["result"] : boolean;
|
|
27
29
|
type FlagValues<FD extends FlagSchema = FlagSchema> = {
|
|
28
30
|
[K in keyof FD]: FlagValue<FD[K]>;
|
|
@@ -39,21 +41,21 @@ type FlagglyOptions<TFlags extends FlagSchema = FlagSchema> = {
|
|
|
39
41
|
*/
|
|
40
42
|
url: string;
|
|
41
43
|
/**
|
|
42
|
-
* The public `
|
|
44
|
+
* The public `user` JWT.
|
|
43
45
|
*/
|
|
44
46
|
apiKey: string;
|
|
45
47
|
/**
|
|
46
|
-
*
|
|
48
|
+
* App for this instance.
|
|
47
49
|
* @default "default"
|
|
48
50
|
*/
|
|
49
51
|
app?: string;
|
|
50
52
|
/**
|
|
51
|
-
*
|
|
53
|
+
* Enviornment for this instance
|
|
52
54
|
* @default "production"
|
|
53
55
|
*/
|
|
54
56
|
env?: string;
|
|
55
57
|
/**
|
|
56
|
-
* By default, flags are evaluated when you
|
|
58
|
+
* By default, flags are evaluated when you initialize the FlagglyClient instance.
|
|
57
59
|
* Pass this as true to manually initiate the flag evaluations.
|
|
58
60
|
* Useful if you just care about feature flags for authenticated users only,
|
|
59
61
|
* and want to evaluate flags when the users log in.
|
|
@@ -61,16 +63,29 @@ type FlagglyOptions<TFlags extends FlagSchema = FlagSchema> = {
|
|
|
61
63
|
*/
|
|
62
64
|
lazy?: boolean;
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* Default values for the feature flags.
|
|
65
67
|
*/
|
|
66
68
|
bootstrap?: Partial<FlagValues<TFlags>>;
|
|
67
69
|
/**
|
|
68
70
|
* Optional method to generate a backup identifer for the flags,
|
|
69
71
|
* for anonymous users when you don't have a stable ID.
|
|
70
|
-
* By default, it
|
|
72
|
+
* By default, it generates and store a value in local storage per app/env.
|
|
71
73
|
* Use this method to pass in your own ID for anonymous users.
|
|
74
|
+
* This is not available server side, where local storage is not available.
|
|
75
|
+
* In that case, this method will default to generate a random ID everytime.
|
|
72
76
|
*/
|
|
73
77
|
getBackupId?: () => string;
|
|
78
|
+
/**
|
|
79
|
+
* Pass in the `fetch` instance to be used when interacting with the API.
|
|
80
|
+
* Used when evaluating flags inside workers.
|
|
81
|
+
* Use a service binding to attach the flaggly worker to your worker and then
|
|
82
|
+
* When passing in the fetch from your service binding, make sure you bind the correct context.
|
|
83
|
+
* Otherwise, use a more explicit approach
|
|
84
|
+
* @example workerFetch: env.FLAGGLY_SERVICE.fetch.bind(env.FLAGGLY_SERVICE)
|
|
85
|
+
* @example workerFetch: (url, init) => env.FLAGGLY_SERVICE.fetch(url, init)
|
|
86
|
+
* @see https://developers.cloudflare.com/workers/observability/errors/#illegal-invocation-errors
|
|
87
|
+
*/
|
|
88
|
+
workerFetch?: typeof fetch;
|
|
74
89
|
};
|
|
75
90
|
declare class Flaggly<TFlags extends FlagSchema = FlagSchema> {
|
|
76
91
|
#private;
|
|
@@ -80,24 +95,73 @@ declare class Flaggly<TFlags extends FlagSchema = FlagSchema> {
|
|
|
80
95
|
private env;
|
|
81
96
|
user?: unknown;
|
|
82
97
|
id?: string;
|
|
98
|
+
workerFetch: typeof fetch;
|
|
83
99
|
getBackupId?: () => string;
|
|
84
|
-
constructor({ url, apiKey, app, env, lazy, bootstrap, getBackupId, }: FlagglyOptions<TFlags>);
|
|
100
|
+
constructor({ url, apiKey, app, env, lazy, bootstrap, getBackupId, workerFetch, }: FlagglyOptions<TFlags>);
|
|
101
|
+
/**
|
|
102
|
+
* Method to identify a user and persist the ID and details for evaluations.
|
|
103
|
+
* Calling this method will evaluate the flags and reset the state.
|
|
104
|
+
* @param id Unique identifier for the user
|
|
105
|
+
* @param user User properties used for flag evaluations
|
|
106
|
+
* @returns
|
|
107
|
+
*/
|
|
85
108
|
identify(id: string, user: unknown): Promise<EvaluatedFlags<TFlags>>;
|
|
86
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Evaluates all flags for a user and updates local state.
|
|
111
|
+
* @param input
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
87
114
|
fetchFlags(input?: FlagInput): Promise<EvaluatedFlags<TFlags>>;
|
|
115
|
+
/**
|
|
116
|
+
* Evaluates a single flag
|
|
117
|
+
* @param key
|
|
118
|
+
* @param input
|
|
119
|
+
* @returns
|
|
120
|
+
*/
|
|
88
121
|
fetchFlag<K extends AllKeys<EvaluatedFlags<TFlags>>>(key: K, input?: FlagInput): Promise<EvaluatedFlags<TFlags>[K]>;
|
|
122
|
+
/**
|
|
123
|
+
* Get all flags
|
|
124
|
+
* @returns
|
|
125
|
+
*/
|
|
89
126
|
getFlags(): EvaluatedFlags<TFlags>;
|
|
127
|
+
/**
|
|
128
|
+
* Get a single flag result
|
|
129
|
+
* @param key
|
|
130
|
+
* @returns
|
|
131
|
+
*/
|
|
90
132
|
getFlag<K extends keyof TFlags>(key: K): FlagValue<TFlags[K]>;
|
|
133
|
+
/**
|
|
134
|
+
* Get a single boolean flag results. Only boolean flag keys are valid.
|
|
135
|
+
* @param key
|
|
136
|
+
* @returns
|
|
137
|
+
*/
|
|
91
138
|
getBooleanFlag<K extends keyof TFlags>(key: K & (TFlags[K] extends {
|
|
92
139
|
type: "boolean";
|
|
93
140
|
} ? K : never)): FlagValue<TFlags[K]> | false;
|
|
141
|
+
/**
|
|
142
|
+
* Get a single boolean flag results. Only variant flag keys are valid.
|
|
143
|
+
* @param key
|
|
144
|
+
* @returns
|
|
145
|
+
*/
|
|
94
146
|
getVariantFlag<K extends keyof TFlags>(key: K & (TFlags[K] extends {
|
|
95
147
|
type: "variant";
|
|
96
148
|
} ? K : never)): FlagValue<TFlags[K]> | null;
|
|
149
|
+
/**
|
|
150
|
+
* Get a single boolean flag results. Only payload flag keys are valid.
|
|
151
|
+
* @param key
|
|
152
|
+
* @returns
|
|
153
|
+
*/
|
|
97
154
|
getPayloadFlag<K extends keyof TFlags>(key: K & (TFlags[K] extends {
|
|
98
155
|
type: "payload";
|
|
99
156
|
} ? K : never)): FlagValue<TFlags[K]> | null;
|
|
157
|
+
/**
|
|
158
|
+
* Subscribe to changes in the flags.
|
|
159
|
+
*/
|
|
100
160
|
onChange(cb: (flags: EvaluatedFlags<TFlags>) => void): () => void;
|
|
161
|
+
/**
|
|
162
|
+
* Local nanostores `map` for interacting with state
|
|
163
|
+
* @see https://github.com/nanostores/nanostores?tab=readme-ov-file#maps
|
|
164
|
+
*/
|
|
101
165
|
get store(): MapStore<EvaluatedFlags<TFlags>>;
|
|
102
166
|
}
|
|
103
167
|
|
package/dist/index.d.ts
CHANGED
|
@@ -22,7 +22,9 @@ type FlagInput = {
|
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
type FlagValue<FR extends FlagConfig = FlagConfig> = FR extends {
|
|
25
|
-
type: "variant"
|
|
25
|
+
type: "variant";
|
|
26
|
+
} ? FR["result"] : FR extends {
|
|
27
|
+
type: "payload";
|
|
26
28
|
} ? FR["result"] : boolean;
|
|
27
29
|
type FlagValues<FD extends FlagSchema = FlagSchema> = {
|
|
28
30
|
[K in keyof FD]: FlagValue<FD[K]>;
|
|
@@ -39,21 +41,21 @@ type FlagglyOptions<TFlags extends FlagSchema = FlagSchema> = {
|
|
|
39
41
|
*/
|
|
40
42
|
url: string;
|
|
41
43
|
/**
|
|
42
|
-
* The public `
|
|
44
|
+
* The public `user` JWT.
|
|
43
45
|
*/
|
|
44
46
|
apiKey: string;
|
|
45
47
|
/**
|
|
46
|
-
*
|
|
48
|
+
* App for this instance.
|
|
47
49
|
* @default "default"
|
|
48
50
|
*/
|
|
49
51
|
app?: string;
|
|
50
52
|
/**
|
|
51
|
-
*
|
|
53
|
+
* Enviornment for this instance
|
|
52
54
|
* @default "production"
|
|
53
55
|
*/
|
|
54
56
|
env?: string;
|
|
55
57
|
/**
|
|
56
|
-
* By default, flags are evaluated when you
|
|
58
|
+
* By default, flags are evaluated when you initialize the FlagglyClient instance.
|
|
57
59
|
* Pass this as true to manually initiate the flag evaluations.
|
|
58
60
|
* Useful if you just care about feature flags for authenticated users only,
|
|
59
61
|
* and want to evaluate flags when the users log in.
|
|
@@ -61,16 +63,29 @@ type FlagglyOptions<TFlags extends FlagSchema = FlagSchema> = {
|
|
|
61
63
|
*/
|
|
62
64
|
lazy?: boolean;
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* Default values for the feature flags.
|
|
65
67
|
*/
|
|
66
68
|
bootstrap?: Partial<FlagValues<TFlags>>;
|
|
67
69
|
/**
|
|
68
70
|
* Optional method to generate a backup identifer for the flags,
|
|
69
71
|
* for anonymous users when you don't have a stable ID.
|
|
70
|
-
* By default, it
|
|
72
|
+
* By default, it generates and store a value in local storage per app/env.
|
|
71
73
|
* Use this method to pass in your own ID for anonymous users.
|
|
74
|
+
* This is not available server side, where local storage is not available.
|
|
75
|
+
* In that case, this method will default to generate a random ID everytime.
|
|
72
76
|
*/
|
|
73
77
|
getBackupId?: () => string;
|
|
78
|
+
/**
|
|
79
|
+
* Pass in the `fetch` instance to be used when interacting with the API.
|
|
80
|
+
* Used when evaluating flags inside workers.
|
|
81
|
+
* Use a service binding to attach the flaggly worker to your worker and then
|
|
82
|
+
* When passing in the fetch from your service binding, make sure you bind the correct context.
|
|
83
|
+
* Otherwise, use a more explicit approach
|
|
84
|
+
* @example workerFetch: env.FLAGGLY_SERVICE.fetch.bind(env.FLAGGLY_SERVICE)
|
|
85
|
+
* @example workerFetch: (url, init) => env.FLAGGLY_SERVICE.fetch(url, init)
|
|
86
|
+
* @see https://developers.cloudflare.com/workers/observability/errors/#illegal-invocation-errors
|
|
87
|
+
*/
|
|
88
|
+
workerFetch?: typeof fetch;
|
|
74
89
|
};
|
|
75
90
|
declare class Flaggly<TFlags extends FlagSchema = FlagSchema> {
|
|
76
91
|
#private;
|
|
@@ -80,24 +95,73 @@ declare class Flaggly<TFlags extends FlagSchema = FlagSchema> {
|
|
|
80
95
|
private env;
|
|
81
96
|
user?: unknown;
|
|
82
97
|
id?: string;
|
|
98
|
+
workerFetch: typeof fetch;
|
|
83
99
|
getBackupId?: () => string;
|
|
84
|
-
constructor({ url, apiKey, app, env, lazy, bootstrap, getBackupId, }: FlagglyOptions<TFlags>);
|
|
100
|
+
constructor({ url, apiKey, app, env, lazy, bootstrap, getBackupId, workerFetch, }: FlagglyOptions<TFlags>);
|
|
101
|
+
/**
|
|
102
|
+
* Method to identify a user and persist the ID and details for evaluations.
|
|
103
|
+
* Calling this method will evaluate the flags and reset the state.
|
|
104
|
+
* @param id Unique identifier for the user
|
|
105
|
+
* @param user User properties used for flag evaluations
|
|
106
|
+
* @returns
|
|
107
|
+
*/
|
|
85
108
|
identify(id: string, user: unknown): Promise<EvaluatedFlags<TFlags>>;
|
|
86
|
-
|
|
109
|
+
/**
|
|
110
|
+
* Evaluates all flags for a user and updates local state.
|
|
111
|
+
* @param input
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
87
114
|
fetchFlags(input?: FlagInput): Promise<EvaluatedFlags<TFlags>>;
|
|
115
|
+
/**
|
|
116
|
+
* Evaluates a single flag
|
|
117
|
+
* @param key
|
|
118
|
+
* @param input
|
|
119
|
+
* @returns
|
|
120
|
+
*/
|
|
88
121
|
fetchFlag<K extends AllKeys<EvaluatedFlags<TFlags>>>(key: K, input?: FlagInput): Promise<EvaluatedFlags<TFlags>[K]>;
|
|
122
|
+
/**
|
|
123
|
+
* Get all flags
|
|
124
|
+
* @returns
|
|
125
|
+
*/
|
|
89
126
|
getFlags(): EvaluatedFlags<TFlags>;
|
|
127
|
+
/**
|
|
128
|
+
* Get a single flag result
|
|
129
|
+
* @param key
|
|
130
|
+
* @returns
|
|
131
|
+
*/
|
|
90
132
|
getFlag<K extends keyof TFlags>(key: K): FlagValue<TFlags[K]>;
|
|
133
|
+
/**
|
|
134
|
+
* Get a single boolean flag results. Only boolean flag keys are valid.
|
|
135
|
+
* @param key
|
|
136
|
+
* @returns
|
|
137
|
+
*/
|
|
91
138
|
getBooleanFlag<K extends keyof TFlags>(key: K & (TFlags[K] extends {
|
|
92
139
|
type: "boolean";
|
|
93
140
|
} ? K : never)): FlagValue<TFlags[K]> | false;
|
|
141
|
+
/**
|
|
142
|
+
* Get a single boolean flag results. Only variant flag keys are valid.
|
|
143
|
+
* @param key
|
|
144
|
+
* @returns
|
|
145
|
+
*/
|
|
94
146
|
getVariantFlag<K extends keyof TFlags>(key: K & (TFlags[K] extends {
|
|
95
147
|
type: "variant";
|
|
96
148
|
} ? K : never)): FlagValue<TFlags[K]> | null;
|
|
149
|
+
/**
|
|
150
|
+
* Get a single boolean flag results. Only payload flag keys are valid.
|
|
151
|
+
* @param key
|
|
152
|
+
* @returns
|
|
153
|
+
*/
|
|
97
154
|
getPayloadFlag<K extends keyof TFlags>(key: K & (TFlags[K] extends {
|
|
98
155
|
type: "payload";
|
|
99
156
|
} ? K : never)): FlagValue<TFlags[K]> | null;
|
|
157
|
+
/**
|
|
158
|
+
* Subscribe to changes in the flags.
|
|
159
|
+
*/
|
|
100
160
|
onChange(cb: (flags: EvaluatedFlags<TFlags>) => void): () => void;
|
|
161
|
+
/**
|
|
162
|
+
* Local nanostores `map` for interacting with state
|
|
163
|
+
* @see https://github.com/nanostores/nanostores?tab=readme-ov-file#maps
|
|
164
|
+
*/
|
|
101
165
|
get store(): MapStore<EvaluatedFlags<TFlags>>;
|
|
102
166
|
}
|
|
103
167
|
|
package/dist/index.js
CHANGED
|
@@ -133,6 +133,7 @@ var Flaggly = class {
|
|
|
133
133
|
env;
|
|
134
134
|
user;
|
|
135
135
|
id;
|
|
136
|
+
workerFetch;
|
|
136
137
|
getBackupId;
|
|
137
138
|
#flags = map();
|
|
138
139
|
constructor({
|
|
@@ -142,13 +143,15 @@ var Flaggly = class {
|
|
|
142
143
|
env = "production",
|
|
143
144
|
lazy = false,
|
|
144
145
|
bootstrap,
|
|
145
|
-
getBackupId
|
|
146
|
+
getBackupId,
|
|
147
|
+
workerFetch
|
|
146
148
|
}) {
|
|
147
149
|
this.url = url;
|
|
148
150
|
this.apiKey = apiKey;
|
|
149
151
|
this.app = app;
|
|
150
152
|
this.env = env;
|
|
151
153
|
this.getBackupId = getBackupId;
|
|
154
|
+
this.workerFetch = workerFetch ?? fetch;
|
|
152
155
|
const defValues = bootstrap ? Object.entries(bootstrap).reduce(
|
|
153
156
|
(acc, [flagKey, flagValue]) => {
|
|
154
157
|
const type = typeof flagValue === "boolean" ? "boolean" : typeof flagValue === "string" ? "variant" : "payload";
|
|
@@ -167,12 +170,19 @@ var Flaggly = class {
|
|
|
167
170
|
this.fetchFlags();
|
|
168
171
|
}
|
|
169
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Method to identify a user and persist the ID and details for evaluations.
|
|
175
|
+
* Calling this method will evaluate the flags and reset the state.
|
|
176
|
+
* @param id Unique identifier for the user
|
|
177
|
+
* @param user User properties used for flag evaluations
|
|
178
|
+
* @returns
|
|
179
|
+
*/
|
|
170
180
|
async identify(id, user) {
|
|
171
181
|
this.id = id;
|
|
172
182
|
this.user = user;
|
|
173
183
|
return await this.fetchFlags({ id, user });
|
|
174
184
|
}
|
|
175
|
-
getPageUrl() {
|
|
185
|
+
#getPageUrl() {
|
|
176
186
|
if ("window" in globalThis) {
|
|
177
187
|
return globalThis.window.location.href;
|
|
178
188
|
}
|
|
@@ -197,7 +207,7 @@ var Flaggly = class {
|
|
|
197
207
|
async #request(path, options = {}) {
|
|
198
208
|
const { method = "POST", body } = options;
|
|
199
209
|
const url = new URL(path, this.url);
|
|
200
|
-
const response = await
|
|
210
|
+
const response = await this.workerFetch(url, {
|
|
201
211
|
method,
|
|
202
212
|
headers: {
|
|
203
213
|
Authorization: `Bearer ${this.apiKey}`,
|
|
@@ -218,6 +228,11 @@ var Flaggly = class {
|
|
|
218
228
|
}
|
|
219
229
|
return response.json();
|
|
220
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Evaluates all flags for a user and updates local state.
|
|
233
|
+
* @param input
|
|
234
|
+
* @returns
|
|
235
|
+
*/
|
|
221
236
|
async fetchFlags(input) {
|
|
222
237
|
const result = await this.#request("/api/eval", {
|
|
223
238
|
method: "POST",
|
|
@@ -225,7 +240,7 @@ var Flaggly = class {
|
|
|
225
240
|
id: input?.id ?? this.id ?? this.#getBackupId(),
|
|
226
241
|
user: input?.user ?? this.user,
|
|
227
242
|
page: {
|
|
228
|
-
url: this
|
|
243
|
+
url: this.#getPageUrl()
|
|
229
244
|
}
|
|
230
245
|
}
|
|
231
246
|
});
|
|
@@ -234,6 +249,12 @@ var Flaggly = class {
|
|
|
234
249
|
}
|
|
235
250
|
return result;
|
|
236
251
|
}
|
|
252
|
+
/**
|
|
253
|
+
* Evaluates a single flag
|
|
254
|
+
* @param key
|
|
255
|
+
* @param input
|
|
256
|
+
* @returns
|
|
257
|
+
*/
|
|
237
258
|
async fetchFlag(key, input) {
|
|
238
259
|
const result = await this.#request(
|
|
239
260
|
`/api/eval/${String(key)}`,
|
|
@@ -243,7 +264,7 @@ var Flaggly = class {
|
|
|
243
264
|
id: input?.id ?? this.id ?? this.#getBackupId(),
|
|
244
265
|
user: input?.user ?? this.user,
|
|
245
266
|
page: {
|
|
246
|
-
url: this
|
|
267
|
+
url: this.#getPageUrl()
|
|
247
268
|
}
|
|
248
269
|
}
|
|
249
270
|
}
|
|
@@ -253,28 +274,59 @@ var Flaggly = class {
|
|
|
253
274
|
}
|
|
254
275
|
return result;
|
|
255
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* Get all flags
|
|
279
|
+
* @returns
|
|
280
|
+
*/
|
|
256
281
|
getFlags() {
|
|
257
282
|
return this.#flags.get();
|
|
258
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* Get a single flag result
|
|
286
|
+
* @param key
|
|
287
|
+
* @returns
|
|
288
|
+
*/
|
|
259
289
|
getFlag(key) {
|
|
260
290
|
const flags = this.#flags.get();
|
|
261
291
|
return flags?.[key]?.result;
|
|
262
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Get a single boolean flag results. Only boolean flag keys are valid.
|
|
295
|
+
* @param key
|
|
296
|
+
* @returns
|
|
297
|
+
*/
|
|
263
298
|
getBooleanFlag(key) {
|
|
264
299
|
const flags = this.#flags.get();
|
|
265
300
|
return flags[key]?.result ?? false;
|
|
266
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* Get a single boolean flag results. Only variant flag keys are valid.
|
|
304
|
+
* @param key
|
|
305
|
+
* @returns
|
|
306
|
+
*/
|
|
267
307
|
getVariantFlag(key) {
|
|
268
308
|
const flags = this.#flags.get();
|
|
269
309
|
return flags[key]?.result ?? null;
|
|
270
310
|
}
|
|
311
|
+
/**
|
|
312
|
+
* Get a single boolean flag results. Only payload flag keys are valid.
|
|
313
|
+
* @param key
|
|
314
|
+
* @returns
|
|
315
|
+
*/
|
|
271
316
|
getPayloadFlag(key) {
|
|
272
317
|
const flags = this.#flags.get();
|
|
273
318
|
return flags[key]?.result ?? null;
|
|
274
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* Subscribe to changes in the flags.
|
|
322
|
+
*/
|
|
275
323
|
onChange(cb) {
|
|
276
324
|
return this.#flags.subscribe(cb);
|
|
277
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Local nanostores `map` for interacting with state
|
|
328
|
+
* @see https://github.com/nanostores/nanostores?tab=readme-ov-file#maps
|
|
329
|
+
*/
|
|
278
330
|
get store() {
|
|
279
331
|
return this.#flags;
|
|
280
332
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -107,6 +107,7 @@ var Flaggly = class {
|
|
|
107
107
|
env;
|
|
108
108
|
user;
|
|
109
109
|
id;
|
|
110
|
+
workerFetch;
|
|
110
111
|
getBackupId;
|
|
111
112
|
#flags = map();
|
|
112
113
|
constructor({
|
|
@@ -116,13 +117,15 @@ var Flaggly = class {
|
|
|
116
117
|
env = "production",
|
|
117
118
|
lazy = false,
|
|
118
119
|
bootstrap,
|
|
119
|
-
getBackupId
|
|
120
|
+
getBackupId,
|
|
121
|
+
workerFetch
|
|
120
122
|
}) {
|
|
121
123
|
this.url = url;
|
|
122
124
|
this.apiKey = apiKey;
|
|
123
125
|
this.app = app;
|
|
124
126
|
this.env = env;
|
|
125
127
|
this.getBackupId = getBackupId;
|
|
128
|
+
this.workerFetch = workerFetch ?? fetch;
|
|
126
129
|
const defValues = bootstrap ? Object.entries(bootstrap).reduce(
|
|
127
130
|
(acc, [flagKey, flagValue]) => {
|
|
128
131
|
const type = typeof flagValue === "boolean" ? "boolean" : typeof flagValue === "string" ? "variant" : "payload";
|
|
@@ -141,12 +144,19 @@ var Flaggly = class {
|
|
|
141
144
|
this.fetchFlags();
|
|
142
145
|
}
|
|
143
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Method to identify a user and persist the ID and details for evaluations.
|
|
149
|
+
* Calling this method will evaluate the flags and reset the state.
|
|
150
|
+
* @param id Unique identifier for the user
|
|
151
|
+
* @param user User properties used for flag evaluations
|
|
152
|
+
* @returns
|
|
153
|
+
*/
|
|
144
154
|
async identify(id, user) {
|
|
145
155
|
this.id = id;
|
|
146
156
|
this.user = user;
|
|
147
157
|
return await this.fetchFlags({ id, user });
|
|
148
158
|
}
|
|
149
|
-
getPageUrl() {
|
|
159
|
+
#getPageUrl() {
|
|
150
160
|
if ("window" in globalThis) {
|
|
151
161
|
return globalThis.window.location.href;
|
|
152
162
|
}
|
|
@@ -171,7 +181,7 @@ var Flaggly = class {
|
|
|
171
181
|
async #request(path, options = {}) {
|
|
172
182
|
const { method = "POST", body } = options;
|
|
173
183
|
const url = new URL(path, this.url);
|
|
174
|
-
const response = await
|
|
184
|
+
const response = await this.workerFetch(url, {
|
|
175
185
|
method,
|
|
176
186
|
headers: {
|
|
177
187
|
Authorization: `Bearer ${this.apiKey}`,
|
|
@@ -192,6 +202,11 @@ var Flaggly = class {
|
|
|
192
202
|
}
|
|
193
203
|
return response.json();
|
|
194
204
|
}
|
|
205
|
+
/**
|
|
206
|
+
* Evaluates all flags for a user and updates local state.
|
|
207
|
+
* @param input
|
|
208
|
+
* @returns
|
|
209
|
+
*/
|
|
195
210
|
async fetchFlags(input) {
|
|
196
211
|
const result = await this.#request("/api/eval", {
|
|
197
212
|
method: "POST",
|
|
@@ -199,7 +214,7 @@ var Flaggly = class {
|
|
|
199
214
|
id: input?.id ?? this.id ?? this.#getBackupId(),
|
|
200
215
|
user: input?.user ?? this.user,
|
|
201
216
|
page: {
|
|
202
|
-
url: this
|
|
217
|
+
url: this.#getPageUrl()
|
|
203
218
|
}
|
|
204
219
|
}
|
|
205
220
|
});
|
|
@@ -208,6 +223,12 @@ var Flaggly = class {
|
|
|
208
223
|
}
|
|
209
224
|
return result;
|
|
210
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Evaluates a single flag
|
|
228
|
+
* @param key
|
|
229
|
+
* @param input
|
|
230
|
+
* @returns
|
|
231
|
+
*/
|
|
211
232
|
async fetchFlag(key, input) {
|
|
212
233
|
const result = await this.#request(
|
|
213
234
|
`/api/eval/${String(key)}`,
|
|
@@ -217,7 +238,7 @@ var Flaggly = class {
|
|
|
217
238
|
id: input?.id ?? this.id ?? this.#getBackupId(),
|
|
218
239
|
user: input?.user ?? this.user,
|
|
219
240
|
page: {
|
|
220
|
-
url: this
|
|
241
|
+
url: this.#getPageUrl()
|
|
221
242
|
}
|
|
222
243
|
}
|
|
223
244
|
}
|
|
@@ -227,28 +248,59 @@ var Flaggly = class {
|
|
|
227
248
|
}
|
|
228
249
|
return result;
|
|
229
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Get all flags
|
|
253
|
+
* @returns
|
|
254
|
+
*/
|
|
230
255
|
getFlags() {
|
|
231
256
|
return this.#flags.get();
|
|
232
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Get a single flag result
|
|
260
|
+
* @param key
|
|
261
|
+
* @returns
|
|
262
|
+
*/
|
|
233
263
|
getFlag(key) {
|
|
234
264
|
const flags = this.#flags.get();
|
|
235
265
|
return flags?.[key]?.result;
|
|
236
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Get a single boolean flag results. Only boolean flag keys are valid.
|
|
269
|
+
* @param key
|
|
270
|
+
* @returns
|
|
271
|
+
*/
|
|
237
272
|
getBooleanFlag(key) {
|
|
238
273
|
const flags = this.#flags.get();
|
|
239
274
|
return flags[key]?.result ?? false;
|
|
240
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Get a single boolean flag results. Only variant flag keys are valid.
|
|
278
|
+
* @param key
|
|
279
|
+
* @returns
|
|
280
|
+
*/
|
|
241
281
|
getVariantFlag(key) {
|
|
242
282
|
const flags = this.#flags.get();
|
|
243
283
|
return flags[key]?.result ?? null;
|
|
244
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Get a single boolean flag results. Only payload flag keys are valid.
|
|
287
|
+
* @param key
|
|
288
|
+
* @returns
|
|
289
|
+
*/
|
|
245
290
|
getPayloadFlag(key) {
|
|
246
291
|
const flags = this.#flags.get();
|
|
247
292
|
return flags[key]?.result ?? null;
|
|
248
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Subscribe to changes in the flags.
|
|
296
|
+
*/
|
|
249
297
|
onChange(cb) {
|
|
250
298
|
return this.#flags.subscribe(cb);
|
|
251
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Local nanostores `map` for interacting with state
|
|
302
|
+
* @see https://github.com/nanostores/nanostores?tab=readme-ov-file#maps
|
|
303
|
+
*/
|
|
252
304
|
get store() {
|
|
253
305
|
return this.#flags;
|
|
254
306
|
}
|