@smplkit/sdk 3.0.22 → 3.0.23
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 +164 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +164 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1772,6 +1772,9 @@ declare class FlagsClient {
|
|
|
1772
1772
|
private _flagBuffer;
|
|
1773
1773
|
private _flagFlushTimer;
|
|
1774
1774
|
private _handles;
|
|
1775
|
+
private _initBackoffMs;
|
|
1776
|
+
private _initRetryTimer;
|
|
1777
|
+
private _wsSubscribed;
|
|
1775
1778
|
private _globalListeners;
|
|
1776
1779
|
private _keyListeners;
|
|
1777
1780
|
private _wsManager;
|
|
@@ -2090,6 +2093,11 @@ declare class FlagRegistrationBuffer {
|
|
|
2090
2093
|
private _seen;
|
|
2091
2094
|
private _pending;
|
|
2092
2095
|
add(decl: FlagDeclaration): void;
|
|
2096
|
+
/** Non-destructive snapshot — items remain in the buffer until committed. */
|
|
2097
|
+
peek(): Array<components["schemas"]["FlagBulkItem"]>;
|
|
2098
|
+
/** Remove successfully-sent items by id. Called after a successful POST. */
|
|
2099
|
+
commit(ids: Set<string>): void;
|
|
2100
|
+
/** Destructively clear the buffer. For teardown / test use only. */
|
|
2093
2101
|
drain(): Array<components["schemas"]["FlagBulkItem"]>;
|
|
2094
2102
|
get pendingCount(): number;
|
|
2095
2103
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1772,6 +1772,9 @@ declare class FlagsClient {
|
|
|
1772
1772
|
private _flagBuffer;
|
|
1773
1773
|
private _flagFlushTimer;
|
|
1774
1774
|
private _handles;
|
|
1775
|
+
private _initBackoffMs;
|
|
1776
|
+
private _initRetryTimer;
|
|
1777
|
+
private _wsSubscribed;
|
|
1775
1778
|
private _globalListeners;
|
|
1776
1779
|
private _keyListeners;
|
|
1777
1780
|
private _wsManager;
|
|
@@ -2090,6 +2093,11 @@ declare class FlagRegistrationBuffer {
|
|
|
2090
2093
|
private _seen;
|
|
2091
2094
|
private _pending;
|
|
2092
2095
|
add(decl: FlagDeclaration): void;
|
|
2096
|
+
/** Non-destructive snapshot — items remain in the buffer until committed. */
|
|
2097
|
+
peek(): Array<components["schemas"]["FlagBulkItem"]>;
|
|
2098
|
+
/** Remove successfully-sent items by id. Called after a successful POST. */
|
|
2099
|
+
commit(ids: Set<string>): void;
|
|
2100
|
+
/** Destructively clear the buffer. For teardown / test use only. */
|
|
2093
2101
|
drain(): Array<components["schemas"]["FlagBulkItem"]>;
|
|
2094
2102
|
get pendingCount(): number;
|
|
2095
2103
|
}
|
package/dist/index.js
CHANGED
|
@@ -19133,6 +19133,15 @@ var FlagRegistrationBuffer = class {
|
|
|
19133
19133
|
environment: decl.environment ?? void 0
|
|
19134
19134
|
});
|
|
19135
19135
|
}
|
|
19136
|
+
/** Non-destructive snapshot — items remain in the buffer until committed. */
|
|
19137
|
+
peek() {
|
|
19138
|
+
return [...this._pending];
|
|
19139
|
+
}
|
|
19140
|
+
/** Remove successfully-sent items by id. Called after a successful POST. */
|
|
19141
|
+
commit(ids) {
|
|
19142
|
+
this._pending = this._pending.filter((item) => !ids.has(item.id));
|
|
19143
|
+
}
|
|
19144
|
+
/** Destructively clear the buffer. For teardown / test use only. */
|
|
19136
19145
|
drain() {
|
|
19137
19146
|
const batch = this._pending;
|
|
19138
19147
|
this._pending = [];
|
|
@@ -19274,10 +19283,13 @@ var ManagementFlagsClient = class {
|
|
|
19274
19283
|
}
|
|
19275
19284
|
/** Send any pending flag declarations to the server. */
|
|
19276
19285
|
async flush() {
|
|
19277
|
-
const batch = this._buffer.
|
|
19286
|
+
const batch = this._buffer.peek();
|
|
19278
19287
|
if (batch.length === 0) return;
|
|
19279
19288
|
try {
|
|
19280
|
-
await this._http.POST("/api/v1/flags/bulk", { body: { flags: batch } });
|
|
19289
|
+
const result = await this._http.POST("/api/v1/flags/bulk", { body: { flags: batch } });
|
|
19290
|
+
if (result.response.ok) {
|
|
19291
|
+
this._buffer.commit(new Set(batch.map((b) => b.id)));
|
|
19292
|
+
}
|
|
19281
19293
|
} catch {
|
|
19282
19294
|
}
|
|
19283
19295
|
}
|
|
@@ -20826,6 +20838,15 @@ var FlagRegistrationBuffer2 = class {
|
|
|
20826
20838
|
});
|
|
20827
20839
|
}
|
|
20828
20840
|
}
|
|
20841
|
+
/** Non-destructive snapshot — items remain in the buffer until committed. */
|
|
20842
|
+
peek() {
|
|
20843
|
+
return [...this._pending];
|
|
20844
|
+
}
|
|
20845
|
+
/** Remove successfully-sent items by id. Called after a successful POST. */
|
|
20846
|
+
commit(ids) {
|
|
20847
|
+
this._pending = this._pending.filter((item) => !ids.has(item.id));
|
|
20848
|
+
}
|
|
20849
|
+
/** Destructively clear the buffer. For teardown / test use only. */
|
|
20829
20850
|
drain() {
|
|
20830
20851
|
const batch = this._pending;
|
|
20831
20852
|
this._pending = [];
|
|
@@ -20854,6 +20875,10 @@ var FlagsClient = class {
|
|
|
20854
20875
|
_flagBuffer = new FlagRegistrationBuffer2();
|
|
20855
20876
|
_flagFlushTimer = null;
|
|
20856
20877
|
_handles = {};
|
|
20878
|
+
// Backoff-retry state for initialize() / _connectInternal()
|
|
20879
|
+
_initBackoffMs = 1e3;
|
|
20880
|
+
_initRetryTimer = null;
|
|
20881
|
+
_wsSubscribed = false;
|
|
20857
20882
|
_globalListeners = [];
|
|
20858
20883
|
_keyListeners = /* @__PURE__ */ new Map();
|
|
20859
20884
|
// Shared WebSocket (set during initialize)
|
|
@@ -20931,7 +20956,14 @@ var FlagsClient = class {
|
|
|
20931
20956
|
this._parent?._environment ?? null
|
|
20932
20957
|
);
|
|
20933
20958
|
if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
|
|
20934
|
-
void this._flushFlags()
|
|
20959
|
+
void this._flushFlags().catch((err) => {
|
|
20960
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
20961
|
+
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
20962
|
+
debug(
|
|
20963
|
+
"registration",
|
|
20964
|
+
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
20965
|
+
);
|
|
20966
|
+
});
|
|
20935
20967
|
}
|
|
20936
20968
|
return handle;
|
|
20937
20969
|
}
|
|
@@ -20957,7 +20989,14 @@ var FlagsClient = class {
|
|
|
20957
20989
|
this._parent?._environment ?? null
|
|
20958
20990
|
);
|
|
20959
20991
|
if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
|
|
20960
|
-
void this._flushFlags()
|
|
20992
|
+
void this._flushFlags().catch((err) => {
|
|
20993
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
20994
|
+
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
20995
|
+
debug(
|
|
20996
|
+
"registration",
|
|
20997
|
+
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
20998
|
+
);
|
|
20999
|
+
});
|
|
20961
21000
|
}
|
|
20962
21001
|
return handle;
|
|
20963
21002
|
}
|
|
@@ -20983,7 +21022,14 @@ var FlagsClient = class {
|
|
|
20983
21022
|
this._parent?._environment ?? null
|
|
20984
21023
|
);
|
|
20985
21024
|
if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
|
|
20986
|
-
void this._flushFlags()
|
|
21025
|
+
void this._flushFlags().catch((err) => {
|
|
21026
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21027
|
+
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
21028
|
+
debug(
|
|
21029
|
+
"registration",
|
|
21030
|
+
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
21031
|
+
);
|
|
21032
|
+
});
|
|
20987
21033
|
}
|
|
20988
21034
|
return handle;
|
|
20989
21035
|
}
|
|
@@ -21009,7 +21055,14 @@ var FlagsClient = class {
|
|
|
21009
21055
|
this._parent?._environment ?? null
|
|
21010
21056
|
);
|
|
21011
21057
|
if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
|
|
21012
|
-
void this._flushFlags()
|
|
21058
|
+
void this._flushFlags().catch((err) => {
|
|
21059
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21060
|
+
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
21061
|
+
debug(
|
|
21062
|
+
"registration",
|
|
21063
|
+
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
21064
|
+
);
|
|
21065
|
+
});
|
|
21013
21066
|
}
|
|
21014
21067
|
return handle;
|
|
21015
21068
|
}
|
|
@@ -21044,19 +21097,51 @@ var FlagsClient = class {
|
|
|
21044
21097
|
if (this._initialized) return;
|
|
21045
21098
|
debug("lifecycle", "FlagsClient.initialize() called");
|
|
21046
21099
|
this._environment = this._parent?._environment ?? null;
|
|
21047
|
-
|
|
21048
|
-
|
|
21100
|
+
try {
|
|
21101
|
+
await this._flushFlags();
|
|
21102
|
+
await this._fetchAllFlags();
|
|
21103
|
+
} catch (err) {
|
|
21104
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21105
|
+
console.warn(`[smplkit] FlagsClient initialization failed (will retry): ${msg}`);
|
|
21106
|
+
if (this._initRetryTimer !== null) {
|
|
21107
|
+
clearTimeout(this._initRetryTimer);
|
|
21108
|
+
this._initRetryTimer = null;
|
|
21109
|
+
}
|
|
21110
|
+
const delay = this._initBackoffMs;
|
|
21111
|
+
this._initBackoffMs = Math.min(this._initBackoffMs * 2, 6e4);
|
|
21112
|
+
this._initRetryTimer = setTimeout(() => {
|
|
21113
|
+
this._initRetryTimer = null;
|
|
21114
|
+
void this.initialize();
|
|
21115
|
+
}, delay);
|
|
21116
|
+
if (typeof this._initRetryTimer === "object" && "unref" in this._initRetryTimer) {
|
|
21117
|
+
this._initRetryTimer.unref();
|
|
21118
|
+
}
|
|
21119
|
+
return;
|
|
21120
|
+
}
|
|
21121
|
+
this._initBackoffMs = 1e3;
|
|
21049
21122
|
this._initialized = true;
|
|
21050
21123
|
this._cache.clear();
|
|
21051
|
-
|
|
21052
|
-
|
|
21053
|
-
|
|
21054
|
-
|
|
21055
|
-
|
|
21056
|
-
|
|
21057
|
-
}
|
|
21058
|
-
if (
|
|
21059
|
-
this._flagFlushTimer
|
|
21124
|
+
if (!this._wsSubscribed) {
|
|
21125
|
+
this._wsManager = this._ensureWs();
|
|
21126
|
+
this._wsManager.on("flag_changed", this._handleFlagChanged);
|
|
21127
|
+
this._wsManager.on("flag_deleted", this._handleFlagDeleted);
|
|
21128
|
+
this._wsManager.on("flags_changed", this._handleFlagsChanged);
|
|
21129
|
+
this._wsSubscribed = true;
|
|
21130
|
+
}
|
|
21131
|
+
if (this._flagFlushTimer === null) {
|
|
21132
|
+
this._flagFlushTimer = setInterval(() => {
|
|
21133
|
+
void this._flushFlags().catch((err) => {
|
|
21134
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21135
|
+
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
21136
|
+
debug(
|
|
21137
|
+
"registration",
|
|
21138
|
+
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
21139
|
+
);
|
|
21140
|
+
});
|
|
21141
|
+
}, FLAG_REGISTRATION_FLUSH_INTERVAL_MS);
|
|
21142
|
+
if (typeof this._flagFlushTimer === "object" && "unref" in this._flagFlushTimer) {
|
|
21143
|
+
this._flagFlushTimer.unref();
|
|
21144
|
+
}
|
|
21060
21145
|
}
|
|
21061
21146
|
}
|
|
21062
21147
|
/**
|
|
@@ -21066,6 +21151,10 @@ var FlagsClient = class {
|
|
|
21066
21151
|
* @internal
|
|
21067
21152
|
*/
|
|
21068
21153
|
_close() {
|
|
21154
|
+
if (this._initRetryTimer !== null) {
|
|
21155
|
+
clearTimeout(this._initRetryTimer);
|
|
21156
|
+
this._initRetryTimer = null;
|
|
21157
|
+
}
|
|
21069
21158
|
if (this._flagFlushTimer !== null) {
|
|
21070
21159
|
clearInterval(this._flagFlushTimer);
|
|
21071
21160
|
this._flagFlushTimer = null;
|
|
@@ -21078,10 +21167,16 @@ var FlagsClient = class {
|
|
|
21078
21167
|
}
|
|
21079
21168
|
this._cache.clear();
|
|
21080
21169
|
this._initialized = false;
|
|
21170
|
+
this._wsSubscribed = false;
|
|
21171
|
+
this._initBackoffMs = 1e3;
|
|
21081
21172
|
this._environment = null;
|
|
21082
21173
|
}
|
|
21083
21174
|
/** Disconnect the flags runtime and release resources. */
|
|
21084
21175
|
async disconnect() {
|
|
21176
|
+
if (this._initRetryTimer !== null) {
|
|
21177
|
+
clearTimeout(this._initRetryTimer);
|
|
21178
|
+
this._initRetryTimer = null;
|
|
21179
|
+
}
|
|
21085
21180
|
if (this._wsManager !== null) {
|
|
21086
21181
|
this._wsManager.off("flag_changed", this._handleFlagChanged);
|
|
21087
21182
|
this._wsManager.off("flag_deleted", this._handleFlagDeleted);
|
|
@@ -21096,6 +21191,8 @@ var FlagsClient = class {
|
|
|
21096
21191
|
this._flagStore = {};
|
|
21097
21192
|
this._cache.clear();
|
|
21098
21193
|
this._initialized = false;
|
|
21194
|
+
this._wsSubscribed = false;
|
|
21195
|
+
this._initBackoffMs = 1e3;
|
|
21099
21196
|
this._environment = null;
|
|
21100
21197
|
}
|
|
21101
21198
|
/** Refresh all flag definitions from the server. */
|
|
@@ -21224,19 +21321,51 @@ var FlagsClient = class {
|
|
|
21224
21321
|
/** @internal — called by SmplClient constructor / lazy init. */
|
|
21225
21322
|
async _connectInternal(environment) {
|
|
21226
21323
|
this._environment = environment;
|
|
21227
|
-
|
|
21228
|
-
|
|
21324
|
+
try {
|
|
21325
|
+
await this._flushFlags();
|
|
21326
|
+
await this._fetchAllFlags();
|
|
21327
|
+
} catch (err) {
|
|
21328
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21329
|
+
console.warn(`[smplkit] FlagsClient initialization failed (will retry): ${msg}`);
|
|
21330
|
+
if (this._initRetryTimer !== null) {
|
|
21331
|
+
clearTimeout(this._initRetryTimer);
|
|
21332
|
+
this._initRetryTimer = null;
|
|
21333
|
+
}
|
|
21334
|
+
const delay = this._initBackoffMs;
|
|
21335
|
+
this._initBackoffMs = Math.min(this._initBackoffMs * 2, 6e4);
|
|
21336
|
+
this._initRetryTimer = setTimeout(() => {
|
|
21337
|
+
this._initRetryTimer = null;
|
|
21338
|
+
void this._connectInternal(environment);
|
|
21339
|
+
}, delay);
|
|
21340
|
+
if (typeof this._initRetryTimer === "object" && "unref" in this._initRetryTimer) {
|
|
21341
|
+
this._initRetryTimer.unref();
|
|
21342
|
+
}
|
|
21343
|
+
return;
|
|
21344
|
+
}
|
|
21345
|
+
this._initBackoffMs = 1e3;
|
|
21229
21346
|
this._initialized = true;
|
|
21230
21347
|
this._cache.clear();
|
|
21231
|
-
|
|
21232
|
-
|
|
21233
|
-
|
|
21234
|
-
|
|
21235
|
-
|
|
21236
|
-
|
|
21237
|
-
}
|
|
21238
|
-
if (
|
|
21239
|
-
this._flagFlushTimer
|
|
21348
|
+
if (!this._wsSubscribed) {
|
|
21349
|
+
this._wsManager = this._ensureWs();
|
|
21350
|
+
this._wsManager.on("flag_changed", this._handleFlagChanged);
|
|
21351
|
+
this._wsManager.on("flag_deleted", this._handleFlagDeleted);
|
|
21352
|
+
this._wsManager.on("flags_changed", this._handleFlagsChanged);
|
|
21353
|
+
this._wsSubscribed = true;
|
|
21354
|
+
}
|
|
21355
|
+
if (this._flagFlushTimer === null) {
|
|
21356
|
+
this._flagFlushTimer = setInterval(() => {
|
|
21357
|
+
void this._flushFlags().catch((err) => {
|
|
21358
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
21359
|
+
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
21360
|
+
debug(
|
|
21361
|
+
"registration",
|
|
21362
|
+
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
21363
|
+
);
|
|
21364
|
+
});
|
|
21365
|
+
}, FLAG_REGISTRATION_FLUSH_INTERVAL_MS);
|
|
21366
|
+
if (typeof this._flagFlushTimer === "object" && "unref" in this._flagFlushTimer) {
|
|
21367
|
+
this._flagFlushTimer.unref();
|
|
21368
|
+
}
|
|
21240
21369
|
}
|
|
21241
21370
|
}
|
|
21242
21371
|
// ------------------------------------------------------------------
|
|
@@ -21395,21 +21524,16 @@ var FlagsClient = class {
|
|
|
21395
21524
|
// Internal: flag registration flush
|
|
21396
21525
|
// ------------------------------------------------------------------
|
|
21397
21526
|
async _flushFlags() {
|
|
21398
|
-
const batch = this._flagBuffer.
|
|
21527
|
+
const batch = this._flagBuffer.peek();
|
|
21399
21528
|
if (batch.length === 0) return;
|
|
21400
21529
|
debug("registration", `flushing ${batch.length} flag(s) to bulk-register endpoint`);
|
|
21401
|
-
|
|
21402
|
-
|
|
21403
|
-
|
|
21404
|
-
|
|
21405
|
-
|
|
21406
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
21407
|
-
console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
|
|
21408
|
-
debug(
|
|
21409
|
-
"registration",
|
|
21410
|
-
`flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
|
|
21411
|
-
);
|
|
21530
|
+
const result = await this._http.POST("/api/v1/flags/bulk", {
|
|
21531
|
+
body: { flags: batch }
|
|
21532
|
+
});
|
|
21533
|
+
if (!result.response.ok) {
|
|
21534
|
+
throw new Error(`HTTP ${result.response.status}`);
|
|
21412
21535
|
}
|
|
21536
|
+
this._flagBuffer.commit(new Set(batch.map((b) => b.id)));
|
|
21413
21537
|
}
|
|
21414
21538
|
// ------------------------------------------------------------------
|
|
21415
21539
|
// Internal: context flush
|