@smplkit/sdk 3.0.0 → 3.0.2
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 +82 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +82 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1429,9 +1429,9 @@ declare class Config {
|
|
|
1429
1429
|
*/
|
|
1430
1430
|
_buildChain(configs?: Config[]): Promise<Array<{
|
|
1431
1431
|
id: string | null;
|
|
1432
|
-
items: Record<string,
|
|
1432
|
+
items: Record<string, unknown>;
|
|
1433
1433
|
environments: Record<string, {
|
|
1434
|
-
values: Record<string,
|
|
1434
|
+
values: Record<string, unknown>;
|
|
1435
1435
|
}>;
|
|
1436
1436
|
}>>;
|
|
1437
1437
|
toString(): string;
|
|
@@ -2409,6 +2409,11 @@ declare class ConfigClient {
|
|
|
2409
2409
|
/** @internal — resolves the management config sub-client used by lazy-init/refresh. */
|
|
2410
2410
|
_resolveManagement?: () => SmplManagementClient;
|
|
2411
2411
|
private _configCache;
|
|
2412
|
+
/** Raw Config objects keyed by id, kept around so a single-config
|
|
2413
|
+
* change (WS event) can refetch one config and rebuild the resolved
|
|
2414
|
+
* cache for everyone (including descendants that inherit from it)
|
|
2415
|
+
* without a full re-list. Mirrors Python's `_raw_config_cache`. */
|
|
2416
|
+
private _configStore;
|
|
2412
2417
|
private _initialized;
|
|
2413
2418
|
private _listeners;
|
|
2414
2419
|
/** @internal */
|
|
@@ -2464,12 +2469,10 @@ declare class ConfigClient {
|
|
|
2464
2469
|
/** @internal — get resolved config from cache. Used by LiveConfigProxy. */
|
|
2465
2470
|
_getCachedConfig(key: string): Record<string, unknown> | undefined;
|
|
2466
2471
|
private _handleConfigChanged;
|
|
2467
|
-
private _handleConfigDeleted;
|
|
2468
|
-
private _handleConfigsChanged;
|
|
2469
2472
|
/** Fetch a single config by key. Returns null if not found. @internal */
|
|
2470
2473
|
private _fetchSingleConfig;
|
|
2471
|
-
|
|
2472
|
-
private
|
|
2474
|
+
private _handleConfigDeleted;
|
|
2475
|
+
private _handleConfigsChanged;
|
|
2473
2476
|
/** @internal */
|
|
2474
2477
|
private _diffAndFire;
|
|
2475
2478
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1429,9 +1429,9 @@ declare class Config {
|
|
|
1429
1429
|
*/
|
|
1430
1430
|
_buildChain(configs?: Config[]): Promise<Array<{
|
|
1431
1431
|
id: string | null;
|
|
1432
|
-
items: Record<string,
|
|
1432
|
+
items: Record<string, unknown>;
|
|
1433
1433
|
environments: Record<string, {
|
|
1434
|
-
values: Record<string,
|
|
1434
|
+
values: Record<string, unknown>;
|
|
1435
1435
|
}>;
|
|
1436
1436
|
}>>;
|
|
1437
1437
|
toString(): string;
|
|
@@ -2409,6 +2409,11 @@ declare class ConfigClient {
|
|
|
2409
2409
|
/** @internal — resolves the management config sub-client used by lazy-init/refresh. */
|
|
2410
2410
|
_resolveManagement?: () => SmplManagementClient;
|
|
2411
2411
|
private _configCache;
|
|
2412
|
+
/** Raw Config objects keyed by id, kept around so a single-config
|
|
2413
|
+
* change (WS event) can refetch one config and rebuild the resolved
|
|
2414
|
+
* cache for everyone (including descendants that inherit from it)
|
|
2415
|
+
* without a full re-list. Mirrors Python's `_raw_config_cache`. */
|
|
2416
|
+
private _configStore;
|
|
2412
2417
|
private _initialized;
|
|
2413
2418
|
private _listeners;
|
|
2414
2419
|
/** @internal */
|
|
@@ -2464,12 +2469,10 @@ declare class ConfigClient {
|
|
|
2464
2469
|
/** @internal — get resolved config from cache. Used by LiveConfigProxy. */
|
|
2465
2470
|
_getCachedConfig(key: string): Record<string, unknown> | undefined;
|
|
2466
2471
|
private _handleConfigChanged;
|
|
2467
|
-
private _handleConfigDeleted;
|
|
2468
|
-
private _handleConfigsChanged;
|
|
2469
2472
|
/** Fetch a single config by key. Returns null if not found. @internal */
|
|
2470
2473
|
private _fetchSingleConfig;
|
|
2471
|
-
|
|
2472
|
-
private
|
|
2474
|
+
private _handleConfigDeleted;
|
|
2475
|
+
private _handleConfigsChanged;
|
|
2473
2476
|
/** @internal */
|
|
2474
2477
|
private _diffAndFire;
|
|
2475
2478
|
}
|
package/dist/index.js
CHANGED
|
@@ -16838,6 +16838,13 @@ function environmentsToWire(environments) {
|
|
|
16838
16838
|
}
|
|
16839
16839
|
return out;
|
|
16840
16840
|
}
|
|
16841
|
+
function environmentsForResolver(environments) {
|
|
16842
|
+
const out = {};
|
|
16843
|
+
for (const [envId, env] of Object.entries(environments)) {
|
|
16844
|
+
out[envId] = { values: env.values };
|
|
16845
|
+
}
|
|
16846
|
+
return out;
|
|
16847
|
+
}
|
|
16841
16848
|
var Config = class {
|
|
16842
16849
|
id;
|
|
16843
16850
|
name;
|
|
@@ -17027,8 +17034,8 @@ var Config = class {
|
|
|
17027
17034
|
const chain = [
|
|
17028
17035
|
{
|
|
17029
17036
|
id: this.id,
|
|
17030
|
-
items: this.
|
|
17031
|
-
environments:
|
|
17037
|
+
items: this.items,
|
|
17038
|
+
environments: environmentsForResolver(this._environments)
|
|
17032
17039
|
}
|
|
17033
17040
|
];
|
|
17034
17041
|
let current = this;
|
|
@@ -17050,8 +17057,8 @@ var Config = class {
|
|
|
17050
17057
|
}
|
|
17051
17058
|
chain.push({
|
|
17052
17059
|
id: parentConfig.id,
|
|
17053
|
-
items: parentConfig.
|
|
17054
|
-
environments:
|
|
17060
|
+
items: parentConfig.items,
|
|
17061
|
+
environments: environmentsForResolver(parentConfig._environments)
|
|
17055
17062
|
});
|
|
17056
17063
|
current = parentConfig;
|
|
17057
17064
|
}
|
|
@@ -17063,6 +17070,22 @@ var Config = class {
|
|
|
17063
17070
|
};
|
|
17064
17071
|
|
|
17065
17072
|
// src/config/proxy.ts
|
|
17073
|
+
function _unflattenDotNotation(flat) {
|
|
17074
|
+
const nested = {};
|
|
17075
|
+
for (const [key, value] of Object.entries(flat)) {
|
|
17076
|
+
const parts = key.split(".");
|
|
17077
|
+
let current = nested;
|
|
17078
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
17079
|
+
const part = parts[i];
|
|
17080
|
+
if (current[part] === void 0 || typeof current[part] !== "object" || current[part] === null) {
|
|
17081
|
+
current[part] = {};
|
|
17082
|
+
}
|
|
17083
|
+
current = current[part];
|
|
17084
|
+
}
|
|
17085
|
+
current[parts[parts.length - 1]] = value;
|
|
17086
|
+
}
|
|
17087
|
+
return nested;
|
|
17088
|
+
}
|
|
17066
17089
|
var LiveConfigProxy = class {
|
|
17067
17090
|
/** @internal */
|
|
17068
17091
|
_client;
|
|
@@ -17085,7 +17108,8 @@ var LiveConfigProxy = class {
|
|
|
17085
17108
|
}
|
|
17086
17109
|
const values = target._currentValues();
|
|
17087
17110
|
if (target._model) {
|
|
17088
|
-
const
|
|
17111
|
+
const nested = _unflattenDotNotation(values);
|
|
17112
|
+
const instance = new target._model(nested);
|
|
17089
17113
|
return instance[prop];
|
|
17090
17114
|
}
|
|
17091
17115
|
return values[prop];
|
|
@@ -17247,6 +17271,11 @@ var ConfigClient = class {
|
|
|
17247
17271
|
/** @internal — resolves the management config sub-client used by lazy-init/refresh. */
|
|
17248
17272
|
_resolveManagement;
|
|
17249
17273
|
_configCache = {};
|
|
17274
|
+
/** Raw Config objects keyed by id, kept around so a single-config
|
|
17275
|
+
* change (WS event) can refetch one config and rebuild the resolved
|
|
17276
|
+
* cache for everyone (including descendants that inherit from it)
|
|
17277
|
+
* without a full re-list. Mirrors Python's `_raw_config_cache`. */
|
|
17278
|
+
_configStore = {};
|
|
17250
17279
|
_initialized = false;
|
|
17251
17280
|
_listeners = [];
|
|
17252
17281
|
/** @internal */
|
|
@@ -17355,12 +17384,15 @@ var ConfigClient = class {
|
|
|
17355
17384
|
}
|
|
17356
17385
|
const configs = await this._listConfigs();
|
|
17357
17386
|
const newCache = {};
|
|
17387
|
+
const newStore = {};
|
|
17358
17388
|
for (const cfg of configs) {
|
|
17359
17389
|
const chain = await cfg._buildChain(configs);
|
|
17360
17390
|
newCache[cfg.id] = resolveChain(chain, environment);
|
|
17391
|
+
newStore[cfg.id] = cfg;
|
|
17361
17392
|
}
|
|
17362
17393
|
const oldCache = this._configCache;
|
|
17363
17394
|
this._configCache = newCache;
|
|
17395
|
+
this._configStore = newStore;
|
|
17364
17396
|
this._diffAndFire(oldCache, newCache, "manual");
|
|
17365
17397
|
}
|
|
17366
17398
|
/**
|
|
@@ -17402,11 +17434,14 @@ var ConfigClient = class {
|
|
|
17402
17434
|
}
|
|
17403
17435
|
const configs = await this._listConfigs();
|
|
17404
17436
|
const cache = {};
|
|
17437
|
+
const store = {};
|
|
17405
17438
|
for (const cfg of configs) {
|
|
17406
17439
|
const chain = await cfg._buildChain(configs);
|
|
17407
17440
|
cache[cfg.id] = resolveChain(chain, environment);
|
|
17441
|
+
store[cfg.id] = cfg;
|
|
17408
17442
|
}
|
|
17409
17443
|
this._configCache = cache;
|
|
17444
|
+
this._configStore = store;
|
|
17410
17445
|
this._initialized = true;
|
|
17411
17446
|
if (this._getSharedWs) {
|
|
17412
17447
|
const ws = this._getSharedWs();
|
|
@@ -17420,11 +17455,14 @@ var ConfigClient = class {
|
|
|
17420
17455
|
if (this._initialized) return;
|
|
17421
17456
|
const configs = await this._listConfigs();
|
|
17422
17457
|
const cache = {};
|
|
17458
|
+
const store = {};
|
|
17423
17459
|
for (const cfg of configs) {
|
|
17424
17460
|
const chain = await cfg._buildChain(configs);
|
|
17425
17461
|
cache[cfg.id] = resolveChain(chain, environment);
|
|
17462
|
+
store[cfg.id] = cfg;
|
|
17426
17463
|
}
|
|
17427
17464
|
this._configCache = cache;
|
|
17465
|
+
this._configStore = store;
|
|
17428
17466
|
this._initialized = true;
|
|
17429
17467
|
}
|
|
17430
17468
|
/** @internal — get resolved config from cache. Used by LiveConfigProxy. */
|
|
@@ -17438,26 +17476,29 @@ var ConfigClient = class {
|
|
|
17438
17476
|
debug("websocket", `config_changed event received: ${JSON.stringify(data)}`);
|
|
17439
17477
|
const configKey = data.id;
|
|
17440
17478
|
if (!configKey) return;
|
|
17479
|
+
const environment = this._parent?._environment;
|
|
17480
|
+
if (!environment) return;
|
|
17441
17481
|
void this._fetchSingleConfig(configKey).then((newConfig) => {
|
|
17442
|
-
const
|
|
17443
|
-
if (
|
|
17444
|
-
|
|
17445
|
-
let newValues;
|
|
17446
|
-
if (newConfig !== null) {
|
|
17447
|
-
newValues = this._resolveConfigValues(newConfig, environment);
|
|
17482
|
+
const newStore = { ...this._configStore };
|
|
17483
|
+
if (newConfig === null) {
|
|
17484
|
+
delete newStore[configKey];
|
|
17448
17485
|
} else {
|
|
17449
|
-
|
|
17450
|
-
}
|
|
17451
|
-
const
|
|
17452
|
-
|
|
17453
|
-
|
|
17454
|
-
|
|
17455
|
-
|
|
17456
|
-
|
|
17457
|
-
|
|
17458
|
-
|
|
17459
|
-
}
|
|
17460
|
-
|
|
17486
|
+
newStore[configKey] = newConfig;
|
|
17487
|
+
}
|
|
17488
|
+
const allConfigs = Object.values(newStore);
|
|
17489
|
+
return Promise.all(
|
|
17490
|
+
allConfigs.map(async (cfg) => {
|
|
17491
|
+
const chain = await cfg._buildChain(allConfigs);
|
|
17492
|
+
return [cfg.id, resolveChain(chain, environment)];
|
|
17493
|
+
})
|
|
17494
|
+
).then((entries) => ({ entries, newStore }));
|
|
17495
|
+
}).then(({ entries, newStore }) => {
|
|
17496
|
+
const newCache = {};
|
|
17497
|
+
for (const [id, values] of entries) newCache[id] = values;
|
|
17498
|
+
const oldCache = this._configCache;
|
|
17499
|
+
this._configCache = newCache;
|
|
17500
|
+
this._configStore = newStore;
|
|
17501
|
+
this._diffAndFire(oldCache, newCache, "websocket");
|
|
17461
17502
|
}).catch((err) => {
|
|
17462
17503
|
debug(
|
|
17463
17504
|
"websocket",
|
|
@@ -17465,6 +17506,20 @@ var ConfigClient = class {
|
|
|
17465
17506
|
);
|
|
17466
17507
|
});
|
|
17467
17508
|
};
|
|
17509
|
+
/** Fetch a single config by key. Returns null if not found. @internal */
|
|
17510
|
+
async _fetchSingleConfig(key) {
|
|
17511
|
+
debug("api", `GET /api/v1/configs/${key}`);
|
|
17512
|
+
try {
|
|
17513
|
+
const result = await this._http.GET("/api/v1/configs/{id}", {
|
|
17514
|
+
params: { path: { id: key } }
|
|
17515
|
+
});
|
|
17516
|
+
if (!result.response.ok) return null;
|
|
17517
|
+
if (!result.data?.data) return null;
|
|
17518
|
+
return resourceToConfig(result.data.data);
|
|
17519
|
+
} catch {
|
|
17520
|
+
return null;
|
|
17521
|
+
}
|
|
17522
|
+
}
|
|
17468
17523
|
_handleConfigDeleted = (data) => {
|
|
17469
17524
|
debug("websocket", `config_deleted event received: ${JSON.stringify(data)}`);
|
|
17470
17525
|
const configKey = data.id;
|
|
@@ -17483,27 +17538,6 @@ var ConfigClient = class {
|
|
|
17483
17538
|
// ------------------------------------------------------------------
|
|
17484
17539
|
// Internal: change detection
|
|
17485
17540
|
// ------------------------------------------------------------------
|
|
17486
|
-
/** Fetch a single config by key. Returns null if not found. @internal */
|
|
17487
|
-
async _fetchSingleConfig(key) {
|
|
17488
|
-
debug("api", `GET /api/v1/configs/${key}`);
|
|
17489
|
-
try {
|
|
17490
|
-
const result = await this._http.GET("/api/v1/configs/{id}", {
|
|
17491
|
-
params: { path: { id: key } }
|
|
17492
|
-
});
|
|
17493
|
-
if (!result.response.ok) return null;
|
|
17494
|
-
if (!result.data?.data) return null;
|
|
17495
|
-
return resourceToConfig(result.data.data);
|
|
17496
|
-
} catch {
|
|
17497
|
-
return null;
|
|
17498
|
-
}
|
|
17499
|
-
}
|
|
17500
|
-
/** Resolve a config's values for an environment (no parent chain). @internal */
|
|
17501
|
-
_resolveConfigValues(config, environment) {
|
|
17502
|
-
const base = config.items ?? {};
|
|
17503
|
-
const envEntry = config.environments?.[environment];
|
|
17504
|
-
if (!envEntry?.values) return { ...base };
|
|
17505
|
-
return { ...base, ...envEntry.values };
|
|
17506
|
-
}
|
|
17507
17541
|
/** @internal */
|
|
17508
17542
|
_diffAndFire(oldCache, newCache, source) {
|
|
17509
17543
|
const allConfigKeys = /* @__PURE__ */ new Set([...Object.keys(oldCache), ...Object.keys(newCache)]);
|
|
@@ -21432,6 +21466,7 @@ var LoggingClient = class {
|
|
|
21432
21466
|
// src/ws.ts
|
|
21433
21467
|
import WebSocket from "ws";
|
|
21434
21468
|
var BACKOFF_MS = [1e3, 2e3, 4e3, 8e3, 16e3, 32e3, 6e4];
|
|
21469
|
+
var SDK_VERSION = "0.0.0";
|
|
21435
21470
|
var SharedWebSocket = class {
|
|
21436
21471
|
_appBaseUrl;
|
|
21437
21472
|
_apiKey;
|
|
@@ -21532,7 +21567,9 @@ var SharedWebSocket = class {
|
|
|
21532
21567
|
const safeUrl = wsUrl.split("?")[0];
|
|
21533
21568
|
debug("websocket", `connecting to ${safeUrl}`);
|
|
21534
21569
|
try {
|
|
21535
|
-
const ws = new WebSocket(wsUrl
|
|
21570
|
+
const ws = new WebSocket(wsUrl, {
|
|
21571
|
+
headers: { "User-Agent": `smplkit-typescript-sdk/${SDK_VERSION}` }
|
|
21572
|
+
});
|
|
21536
21573
|
this._ws = ws;
|
|
21537
21574
|
ws.on("open", () => {
|
|
21538
21575
|
if (this._closed) {
|