@smplkit/sdk 3.0.21 → 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.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
@@ -16730,19 +16730,20 @@ var AuditEventBuffer = class {
16730
16730
 
16731
16731
  // src/audit/client.ts
16732
16732
  var JSONAPI_CONTENT_TYPE = "application/vnd.api+json";
16733
- function _attributesFromInput(input) {
16733
+ function _eventBodyFromInput(input) {
16734
16734
  const attrs = {
16735
16735
  action: input.action,
16736
16736
  resource_type: input.resourceType,
16737
- resource_id: input.resourceId
16737
+ resource_id: input.resourceId,
16738
+ do_not_forward: input.doNotForward ?? false
16738
16739
  };
16739
16740
  if (input.occurredAt !== void 0) {
16740
- const ts = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : input.occurredAt;
16741
- attrs.occurred_at = ts;
16741
+ attrs.occurred_at = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : input.occurredAt;
16742
16742
  }
16743
- if (input.data !== void 0) attrs.data = input.data;
16744
- if (input.doNotForward) attrs.do_not_forward = true;
16745
- return attrs;
16743
+ if (input.data !== void 0) {
16744
+ attrs.data = input.data;
16745
+ }
16746
+ return { data: { id: "", type: "event", attributes: attrs } };
16746
16747
  }
16747
16748
  function _eventFromResource(resource) {
16748
16749
  const attrs = resource.attributes;
@@ -16791,9 +16792,13 @@ function _forwarderAttributes(input) {
16791
16792
  enabled: input.enabled ?? true,
16792
16793
  http: _httpToWire(input.http)
16793
16794
  };
16794
- if (input.filter !== void 0) attrs.filter = input.filter;
16795
+ if (input.filter !== void 0) {
16796
+ attrs.filter = input.filter;
16797
+ }
16795
16798
  if (input.transform !== void 0) attrs.transform = input.transform;
16796
- if (input.data !== void 0) attrs.data = input.data;
16799
+ if (input.data !== void 0) {
16800
+ attrs.data = input.data;
16801
+ }
16797
16802
  return attrs;
16798
16803
  }
16799
16804
  function _forwarderFromResource(resource) {
@@ -16857,9 +16862,6 @@ var EventsClient = class {
16857
16862
  const headerInit = {};
16858
16863
  if (item.idempotencyKey !== null) headerInit["Idempotency-Key"] = item.idempotencyKey;
16859
16864
  const result = await this._http.POST("/api/v1/events", {
16860
- // Casting through unknown because the generated body type is
16861
- // EventResponse with id required, while the wrapper builds an
16862
- // unsaved-resource body without an id (server assigns).
16863
16865
  body: item.body,
16864
16866
  headers: headerInit
16865
16867
  });
@@ -16879,10 +16881,7 @@ var EventsClient = class {
16879
16881
  * failures, so a misuse will silently disappear from the queue).
16880
16882
  */
16881
16883
  record(input) {
16882
- const body = {
16883
- data: { id: "", type: "event", attributes: _attributesFromInput(input) }
16884
- };
16885
- this._buffer.enqueue(body, input.idempotencyKey ?? null);
16884
+ this._buffer.enqueue(_eventBodyFromInput(input), input.idempotencyKey ?? null);
16886
16885
  }
16887
16886
  async list(params = {}) {
16888
16887
  const query = {};
@@ -17012,10 +17011,10 @@ var ForwardersClient = class {
17012
17011
  deliveries;
17013
17012
  actions;
17014
17013
  async create(input) {
17015
- const body = { data: { id: "", type: "forwarder", attributes: _forwarderAttributes(input) } };
17016
- const result = await this._http.POST("/api/v1/forwarders", {
17017
- body
17018
- });
17014
+ const body = {
17015
+ data: { id: "", type: "forwarder", attributes: _forwarderAttributes(input) }
17016
+ };
17017
+ const result = await this._http.POST("/api/v1/forwarders", { body });
17019
17018
  if (!result.response.ok || result.data === void 0) {
17020
17019
  throw new Error(
17021
17020
  `audit create forwarder failed: ${result.response.status} ${result.response.statusText}`
@@ -19134,6 +19133,15 @@ var FlagRegistrationBuffer = class {
19134
19133
  environment: decl.environment ?? void 0
19135
19134
  });
19136
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. */
19137
19145
  drain() {
19138
19146
  const batch = this._pending;
19139
19147
  this._pending = [];
@@ -19275,10 +19283,13 @@ var ManagementFlagsClient = class {
19275
19283
  }
19276
19284
  /** Send any pending flag declarations to the server. */
19277
19285
  async flush() {
19278
- const batch = this._buffer.drain();
19286
+ const batch = this._buffer.peek();
19279
19287
  if (batch.length === 0) return;
19280
19288
  try {
19281
- 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
+ }
19282
19293
  } catch {
19283
19294
  }
19284
19295
  }
@@ -20827,6 +20838,15 @@ var FlagRegistrationBuffer2 = class {
20827
20838
  });
20828
20839
  }
20829
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. */
20830
20850
  drain() {
20831
20851
  const batch = this._pending;
20832
20852
  this._pending = [];
@@ -20855,6 +20875,10 @@ var FlagsClient = class {
20855
20875
  _flagBuffer = new FlagRegistrationBuffer2();
20856
20876
  _flagFlushTimer = null;
20857
20877
  _handles = {};
20878
+ // Backoff-retry state for initialize() / _connectInternal()
20879
+ _initBackoffMs = 1e3;
20880
+ _initRetryTimer = null;
20881
+ _wsSubscribed = false;
20858
20882
  _globalListeners = [];
20859
20883
  _keyListeners = /* @__PURE__ */ new Map();
20860
20884
  // Shared WebSocket (set during initialize)
@@ -20932,7 +20956,14 @@ var FlagsClient = class {
20932
20956
  this._parent?._environment ?? null
20933
20957
  );
20934
20958
  if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
20935
- 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
+ });
20936
20967
  }
20937
20968
  return handle;
20938
20969
  }
@@ -20958,7 +20989,14 @@ var FlagsClient = class {
20958
20989
  this._parent?._environment ?? null
20959
20990
  );
20960
20991
  if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
20961
- 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
+ });
20962
21000
  }
20963
21001
  return handle;
20964
21002
  }
@@ -20984,7 +21022,14 @@ var FlagsClient = class {
20984
21022
  this._parent?._environment ?? null
20985
21023
  );
20986
21024
  if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
20987
- 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
+ });
20988
21033
  }
20989
21034
  return handle;
20990
21035
  }
@@ -21010,7 +21055,14 @@ var FlagsClient = class {
21010
21055
  this._parent?._environment ?? null
21011
21056
  );
21012
21057
  if (this._flagBuffer.pendingCount >= FLAG_REGISTRATION_FLUSH_SIZE2) {
21013
- 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
+ });
21014
21066
  }
21015
21067
  return handle;
21016
21068
  }
@@ -21045,19 +21097,51 @@ var FlagsClient = class {
21045
21097
  if (this._initialized) return;
21046
21098
  debug("lifecycle", "FlagsClient.initialize() called");
21047
21099
  this._environment = this._parent?._environment ?? null;
21048
- await this._flushFlags();
21049
- await this._fetchAllFlags();
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;
21050
21122
  this._initialized = true;
21051
21123
  this._cache.clear();
21052
- this._wsManager = this._ensureWs();
21053
- this._wsManager.on("flag_changed", this._handleFlagChanged);
21054
- this._wsManager.on("flag_deleted", this._handleFlagDeleted);
21055
- this._wsManager.on("flags_changed", this._handleFlagsChanged);
21056
- this._flagFlushTimer = setInterval(() => {
21057
- void this._flushFlags();
21058
- }, FLAG_REGISTRATION_FLUSH_INTERVAL_MS);
21059
- if (typeof this._flagFlushTimer === "object" && "unref" in this._flagFlushTimer) {
21060
- this._flagFlushTimer.unref();
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
+ }
21061
21145
  }
21062
21146
  }
21063
21147
  /**
@@ -21067,6 +21151,10 @@ var FlagsClient = class {
21067
21151
  * @internal
21068
21152
  */
21069
21153
  _close() {
21154
+ if (this._initRetryTimer !== null) {
21155
+ clearTimeout(this._initRetryTimer);
21156
+ this._initRetryTimer = null;
21157
+ }
21070
21158
  if (this._flagFlushTimer !== null) {
21071
21159
  clearInterval(this._flagFlushTimer);
21072
21160
  this._flagFlushTimer = null;
@@ -21079,10 +21167,16 @@ var FlagsClient = class {
21079
21167
  }
21080
21168
  this._cache.clear();
21081
21169
  this._initialized = false;
21170
+ this._wsSubscribed = false;
21171
+ this._initBackoffMs = 1e3;
21082
21172
  this._environment = null;
21083
21173
  }
21084
21174
  /** Disconnect the flags runtime and release resources. */
21085
21175
  async disconnect() {
21176
+ if (this._initRetryTimer !== null) {
21177
+ clearTimeout(this._initRetryTimer);
21178
+ this._initRetryTimer = null;
21179
+ }
21086
21180
  if (this._wsManager !== null) {
21087
21181
  this._wsManager.off("flag_changed", this._handleFlagChanged);
21088
21182
  this._wsManager.off("flag_deleted", this._handleFlagDeleted);
@@ -21097,6 +21191,8 @@ var FlagsClient = class {
21097
21191
  this._flagStore = {};
21098
21192
  this._cache.clear();
21099
21193
  this._initialized = false;
21194
+ this._wsSubscribed = false;
21195
+ this._initBackoffMs = 1e3;
21100
21196
  this._environment = null;
21101
21197
  }
21102
21198
  /** Refresh all flag definitions from the server. */
@@ -21225,19 +21321,51 @@ var FlagsClient = class {
21225
21321
  /** @internal — called by SmplClient constructor / lazy init. */
21226
21322
  async _connectInternal(environment) {
21227
21323
  this._environment = environment;
21228
- await this._flushFlags();
21229
- await this._fetchAllFlags();
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;
21230
21346
  this._initialized = true;
21231
21347
  this._cache.clear();
21232
- this._wsManager = this._ensureWs();
21233
- this._wsManager.on("flag_changed", this._handleFlagChanged);
21234
- this._wsManager.on("flag_deleted", this._handleFlagDeleted);
21235
- this._wsManager.on("flags_changed", this._handleFlagsChanged);
21236
- this._flagFlushTimer = setInterval(() => {
21237
- void this._flushFlags();
21238
- }, FLAG_REGISTRATION_FLUSH_INTERVAL_MS);
21239
- if (typeof this._flagFlushTimer === "object" && "unref" in this._flagFlushTimer) {
21240
- this._flagFlushTimer.unref();
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
+ }
21241
21369
  }
21242
21370
  }
21243
21371
  // ------------------------------------------------------------------
@@ -21396,21 +21524,16 @@ var FlagsClient = class {
21396
21524
  // Internal: flag registration flush
21397
21525
  // ------------------------------------------------------------------
21398
21526
  async _flushFlags() {
21399
- const batch = this._flagBuffer.drain();
21527
+ const batch = this._flagBuffer.peek();
21400
21528
  if (batch.length === 0) return;
21401
21529
  debug("registration", `flushing ${batch.length} flag(s) to bulk-register endpoint`);
21402
- try {
21403
- await this._http.POST("/api/v1/flags/bulk", {
21404
- body: { flags: batch }
21405
- });
21406
- } catch (err) {
21407
- const msg = err instanceof Error ? err.message : String(err);
21408
- console.warn(`[smplkit] Failed to bulk-register flags: ${msg}`);
21409
- debug(
21410
- "registration",
21411
- `flag bulk-register error: ${err instanceof Error ? err.stack ?? msg : msg}`
21412
- );
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}`);
21413
21535
  }
21536
+ this._flagBuffer.commit(new Set(batch.map((b) => b.id)));
21414
21537
  }
21415
21538
  // ------------------------------------------------------------------
21416
21539
  // Internal: context flush