@shipeasy/sdk 1.0.0 → 1.1.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 +40 -0
- package/README.md +94 -0
- package/dist/client/index.d.mts +132 -7
- package/dist/client/index.d.ts +132 -7
- package/dist/client/index.js +487 -25
- package/dist/client/index.mjs +476 -25
- package/dist/server/index.d.mts +24 -1
- package/dist/server/index.d.ts +24 -1
- package/dist/server/index.js +62 -1
- package/dist/server/index.mjs +58 -1
- package/package.json +30 -6
package/dist/server/index.js
CHANGED
|
@@ -21,6 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var server_exports = {};
|
|
22
22
|
__export(server_exports, {
|
|
23
23
|
FlagsClient: () => FlagsClient,
|
|
24
|
+
_resetShipeasyServerForTests: () => _resetShipeasyServerForTests,
|
|
25
|
+
configureShipeasyServer: () => configureShipeasyServer,
|
|
26
|
+
flags: () => flags,
|
|
27
|
+
getShipeasyServerClient: () => getShipeasyServerClient,
|
|
24
28
|
version: () => version
|
|
25
29
|
});
|
|
26
30
|
module.exports = __toCommonJS(server_exports);
|
|
@@ -127,6 +131,7 @@ function evalGateInternal(gate, user) {
|
|
|
127
131
|
var FlagsClient = class {
|
|
128
132
|
apiKey;
|
|
129
133
|
baseUrl;
|
|
134
|
+
env;
|
|
130
135
|
flagsBlob = null;
|
|
131
136
|
expsBlob = null;
|
|
132
137
|
flagsEtag = null;
|
|
@@ -137,6 +142,7 @@ var FlagsClient = class {
|
|
|
137
142
|
constructor(opts) {
|
|
138
143
|
this.apiKey = opts.apiKey;
|
|
139
144
|
this.baseUrl = (opts.baseUrl ?? "https://edge.shipeasy.dev").replace(/\/$/, "");
|
|
145
|
+
this.env = opts.env ?? "prod";
|
|
140
146
|
}
|
|
141
147
|
async init() {
|
|
142
148
|
await this.fetchAll();
|
|
@@ -174,7 +180,7 @@ var FlagsClient = class {
|
|
|
174
180
|
async fetchFlags() {
|
|
175
181
|
const headers = { "X-SDK-Key": this.apiKey };
|
|
176
182
|
if (this.flagsEtag) headers["If-None-Match"] = this.flagsEtag;
|
|
177
|
-
const res = await globalThis.fetch(`${this.baseUrl}/sdk/flags`, { headers });
|
|
183
|
+
const res = await globalThis.fetch(`${this.baseUrl}/sdk/flags?env=${this.env}`, { headers });
|
|
178
184
|
const interval = Number(res.headers.get("X-Poll-Interval") ?? "30") || 30;
|
|
179
185
|
if (res.status === 304) return interval;
|
|
180
186
|
if (!res.ok) throw new Error(`/sdk/flags returned ${res.status}`);
|
|
@@ -265,8 +271,63 @@ var FlagsClient = class {
|
|
|
265
271
|
}).catch((err) => console.warn("[shipeasy] track failed:", String(err)));
|
|
266
272
|
}
|
|
267
273
|
};
|
|
274
|
+
var _server = null;
|
|
275
|
+
function configureShipeasyServer(opts) {
|
|
276
|
+
if (_server) return _server;
|
|
277
|
+
_server = new FlagsClient(opts);
|
|
278
|
+
return _server;
|
|
279
|
+
}
|
|
280
|
+
function getShipeasyServerClient() {
|
|
281
|
+
return _server;
|
|
282
|
+
}
|
|
283
|
+
function _resetShipeasyServerForTests() {
|
|
284
|
+
_server?.destroy();
|
|
285
|
+
_server = null;
|
|
286
|
+
}
|
|
287
|
+
var flags = {
|
|
288
|
+
configure(opts) {
|
|
289
|
+
configureShipeasyServer(opts);
|
|
290
|
+
},
|
|
291
|
+
/**
|
|
292
|
+
* Long-running server: starts the background poll. Call once at app boot.
|
|
293
|
+
* Throws if the initial fetch fails (caller decides whether to crash or degrade).
|
|
294
|
+
*/
|
|
295
|
+
init() {
|
|
296
|
+
if (!_server) throw new Error("[shipeasy] flags.init called before configure()");
|
|
297
|
+
return _server.init();
|
|
298
|
+
},
|
|
299
|
+
/** Serverless / edge: fetch rules once, no background timer. */
|
|
300
|
+
initOnce() {
|
|
301
|
+
if (!_server) throw new Error("[shipeasy] flags.initOnce called before configure()");
|
|
302
|
+
return _server.initOnce();
|
|
303
|
+
},
|
|
304
|
+
/** Stop background timers. Safe to call repeatedly. */
|
|
305
|
+
destroy() {
|
|
306
|
+
_server?.destroy();
|
|
307
|
+
},
|
|
308
|
+
get(name, user) {
|
|
309
|
+
return _server?.getFlag(name, user) ?? false;
|
|
310
|
+
},
|
|
311
|
+
getConfig(name, decode) {
|
|
312
|
+
return _server?.getConfig(name, decode);
|
|
313
|
+
},
|
|
314
|
+
getExperiment(name, user, defaultParams, decode) {
|
|
315
|
+
return _server?.getExperiment(name, user, defaultParams, decode) ?? {
|
|
316
|
+
inExperiment: false,
|
|
317
|
+
group: "control",
|
|
318
|
+
params: defaultParams
|
|
319
|
+
};
|
|
320
|
+
},
|
|
321
|
+
track(userId, eventName, props) {
|
|
322
|
+
_server?.track(userId, eventName, props);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
268
325
|
// Annotate the CommonJS export names for ESM import in node:
|
|
269
326
|
0 && (module.exports = {
|
|
270
327
|
FlagsClient,
|
|
328
|
+
_resetShipeasyServerForTests,
|
|
329
|
+
configureShipeasyServer,
|
|
330
|
+
flags,
|
|
331
|
+
getShipeasyServerClient,
|
|
271
332
|
version
|
|
272
333
|
});
|
package/dist/server/index.mjs
CHANGED
|
@@ -102,6 +102,7 @@ function evalGateInternal(gate, user) {
|
|
|
102
102
|
var FlagsClient = class {
|
|
103
103
|
apiKey;
|
|
104
104
|
baseUrl;
|
|
105
|
+
env;
|
|
105
106
|
flagsBlob = null;
|
|
106
107
|
expsBlob = null;
|
|
107
108
|
flagsEtag = null;
|
|
@@ -112,6 +113,7 @@ var FlagsClient = class {
|
|
|
112
113
|
constructor(opts) {
|
|
113
114
|
this.apiKey = opts.apiKey;
|
|
114
115
|
this.baseUrl = (opts.baseUrl ?? "https://edge.shipeasy.dev").replace(/\/$/, "");
|
|
116
|
+
this.env = opts.env ?? "prod";
|
|
115
117
|
}
|
|
116
118
|
async init() {
|
|
117
119
|
await this.fetchAll();
|
|
@@ -149,7 +151,7 @@ var FlagsClient = class {
|
|
|
149
151
|
async fetchFlags() {
|
|
150
152
|
const headers = { "X-SDK-Key": this.apiKey };
|
|
151
153
|
if (this.flagsEtag) headers["If-None-Match"] = this.flagsEtag;
|
|
152
|
-
const res = await globalThis.fetch(`${this.baseUrl}/sdk/flags`, { headers });
|
|
154
|
+
const res = await globalThis.fetch(`${this.baseUrl}/sdk/flags?env=${this.env}`, { headers });
|
|
153
155
|
const interval = Number(res.headers.get("X-Poll-Interval") ?? "30") || 30;
|
|
154
156
|
if (res.status === 304) return interval;
|
|
155
157
|
if (!res.ok) throw new Error(`/sdk/flags returned ${res.status}`);
|
|
@@ -240,7 +242,62 @@ var FlagsClient = class {
|
|
|
240
242
|
}).catch((err) => console.warn("[shipeasy] track failed:", String(err)));
|
|
241
243
|
}
|
|
242
244
|
};
|
|
245
|
+
var _server = null;
|
|
246
|
+
function configureShipeasyServer(opts) {
|
|
247
|
+
if (_server) return _server;
|
|
248
|
+
_server = new FlagsClient(opts);
|
|
249
|
+
return _server;
|
|
250
|
+
}
|
|
251
|
+
function getShipeasyServerClient() {
|
|
252
|
+
return _server;
|
|
253
|
+
}
|
|
254
|
+
function _resetShipeasyServerForTests() {
|
|
255
|
+
_server?.destroy();
|
|
256
|
+
_server = null;
|
|
257
|
+
}
|
|
258
|
+
var flags = {
|
|
259
|
+
configure(opts) {
|
|
260
|
+
configureShipeasyServer(opts);
|
|
261
|
+
},
|
|
262
|
+
/**
|
|
263
|
+
* Long-running server: starts the background poll. Call once at app boot.
|
|
264
|
+
* Throws if the initial fetch fails (caller decides whether to crash or degrade).
|
|
265
|
+
*/
|
|
266
|
+
init() {
|
|
267
|
+
if (!_server) throw new Error("[shipeasy] flags.init called before configure()");
|
|
268
|
+
return _server.init();
|
|
269
|
+
},
|
|
270
|
+
/** Serverless / edge: fetch rules once, no background timer. */
|
|
271
|
+
initOnce() {
|
|
272
|
+
if (!_server) throw new Error("[shipeasy] flags.initOnce called before configure()");
|
|
273
|
+
return _server.initOnce();
|
|
274
|
+
},
|
|
275
|
+
/** Stop background timers. Safe to call repeatedly. */
|
|
276
|
+
destroy() {
|
|
277
|
+
_server?.destroy();
|
|
278
|
+
},
|
|
279
|
+
get(name, user) {
|
|
280
|
+
return _server?.getFlag(name, user) ?? false;
|
|
281
|
+
},
|
|
282
|
+
getConfig(name, decode) {
|
|
283
|
+
return _server?.getConfig(name, decode);
|
|
284
|
+
},
|
|
285
|
+
getExperiment(name, user, defaultParams, decode) {
|
|
286
|
+
return _server?.getExperiment(name, user, defaultParams, decode) ?? {
|
|
287
|
+
inExperiment: false,
|
|
288
|
+
group: "control",
|
|
289
|
+
params: defaultParams
|
|
290
|
+
};
|
|
291
|
+
},
|
|
292
|
+
track(userId, eventName, props) {
|
|
293
|
+
_server?.track(userId, eventName, props);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
243
296
|
export {
|
|
244
297
|
FlagsClient,
|
|
298
|
+
_resetShipeasyServerForTests,
|
|
299
|
+
configureShipeasyServer,
|
|
300
|
+
flags,
|
|
301
|
+
getShipeasyServerClient,
|
|
245
302
|
version
|
|
246
303
|
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipeasy/sdk",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Shipeasy SDK — feature gates, runtime configs, experiments, and metrics for the Shipeasy hosted service.",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
|
+
"homepage": "https://shipeasy.ai",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/shipeasy-ai/sdk.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/shipeasy-ai/sdk/issues"
|
|
13
|
+
},
|
|
5
14
|
"main": "./dist/server/index.js",
|
|
6
15
|
"module": "./dist/server/index.mjs",
|
|
7
16
|
"browser": "./dist/client/index.js",
|
|
17
|
+
"typesVersions": {
|
|
18
|
+
"*": {
|
|
19
|
+
"client": ["./dist/client/index.d.ts"],
|
|
20
|
+
"server": ["./dist/server/index.d.ts"]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
8
23
|
"exports": {
|
|
9
24
|
".": {
|
|
10
25
|
"node": "./dist/server/index.js",
|
|
@@ -23,13 +38,18 @@
|
|
|
23
38
|
"./templates/*": "./templates/*.js"
|
|
24
39
|
},
|
|
25
40
|
"files": [
|
|
26
|
-
"dist/",
|
|
27
|
-
"
|
|
41
|
+
"dist/server/",
|
|
42
|
+
"dist/client/",
|
|
43
|
+
"templates/",
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"README.md"
|
|
28
46
|
],
|
|
29
47
|
"scripts": {
|
|
30
48
|
"build": "tsup",
|
|
31
49
|
"type-check": "tsc --noEmit",
|
|
32
|
-
"test": "vitest"
|
|
50
|
+
"test": "vitest run",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"publish-loader": "wrangler r2 object put shipeasy-sdk/loader-v$npm_package_version.js --file=dist/loader/loader.global.js --content-type 'application/javascript; charset=utf-8' --cache-control 'public, max-age=31536000, immutable' --remote && wrangler r2 object put shipeasy-sdk/loader.js --file=dist/loader/loader.global.js --content-type 'application/javascript; charset=utf-8' --cache-control 'public, max-age=300' --remote"
|
|
33
53
|
},
|
|
34
54
|
"dependencies": {
|
|
35
55
|
"murmurhash-js": "^1.0.0"
|
|
@@ -38,7 +58,8 @@
|
|
|
38
58
|
"@types/murmurhash-js": "^1.0.6",
|
|
39
59
|
"tsup": "^8.3.0",
|
|
40
60
|
"typescript": "^5.7.4",
|
|
41
|
-
"vitest": "^2.1.0"
|
|
61
|
+
"vitest": "^2.1.0",
|
|
62
|
+
"wrangler": "^4.83.0"
|
|
42
63
|
},
|
|
43
64
|
"peerDependencies": {
|
|
44
65
|
"zod": "^4.0.0"
|
|
@@ -50,5 +71,8 @@
|
|
|
50
71
|
},
|
|
51
72
|
"publishConfig": {
|
|
52
73
|
"access": "public"
|
|
74
|
+
},
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": ">=20"
|
|
53
77
|
}
|
|
54
78
|
}
|