@smplkit/sdk 3.0.1 → 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 +78 -44
- 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 +78 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -16903,6 +16903,13 @@ function environmentsToWire(environments) {
|
|
|
16903
16903
|
}
|
|
16904
16904
|
return out;
|
|
16905
16905
|
}
|
|
16906
|
+
function environmentsForResolver(environments) {
|
|
16907
|
+
const out = {};
|
|
16908
|
+
for (const [envId, env] of Object.entries(environments)) {
|
|
16909
|
+
out[envId] = { values: env.values };
|
|
16910
|
+
}
|
|
16911
|
+
return out;
|
|
16912
|
+
}
|
|
16906
16913
|
var Config = class {
|
|
16907
16914
|
id;
|
|
16908
16915
|
name;
|
|
@@ -17092,8 +17099,8 @@ var Config = class {
|
|
|
17092
17099
|
const chain = [
|
|
17093
17100
|
{
|
|
17094
17101
|
id: this.id,
|
|
17095
|
-
items: this.
|
|
17096
|
-
environments:
|
|
17102
|
+
items: this.items,
|
|
17103
|
+
environments: environmentsForResolver(this._environments)
|
|
17097
17104
|
}
|
|
17098
17105
|
];
|
|
17099
17106
|
let current = this;
|
|
@@ -17115,8 +17122,8 @@ var Config = class {
|
|
|
17115
17122
|
}
|
|
17116
17123
|
chain.push({
|
|
17117
17124
|
id: parentConfig.id,
|
|
17118
|
-
items: parentConfig.
|
|
17119
|
-
environments:
|
|
17125
|
+
items: parentConfig.items,
|
|
17126
|
+
environments: environmentsForResolver(parentConfig._environments)
|
|
17120
17127
|
});
|
|
17121
17128
|
current = parentConfig;
|
|
17122
17129
|
}
|
|
@@ -17128,6 +17135,22 @@ var Config = class {
|
|
|
17128
17135
|
};
|
|
17129
17136
|
|
|
17130
17137
|
// src/config/proxy.ts
|
|
17138
|
+
function _unflattenDotNotation(flat) {
|
|
17139
|
+
const nested = {};
|
|
17140
|
+
for (const [key, value] of Object.entries(flat)) {
|
|
17141
|
+
const parts = key.split(".");
|
|
17142
|
+
let current = nested;
|
|
17143
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
17144
|
+
const part = parts[i];
|
|
17145
|
+
if (current[part] === void 0 || typeof current[part] !== "object" || current[part] === null) {
|
|
17146
|
+
current[part] = {};
|
|
17147
|
+
}
|
|
17148
|
+
current = current[part];
|
|
17149
|
+
}
|
|
17150
|
+
current[parts[parts.length - 1]] = value;
|
|
17151
|
+
}
|
|
17152
|
+
return nested;
|
|
17153
|
+
}
|
|
17131
17154
|
var LiveConfigProxy = class {
|
|
17132
17155
|
/** @internal */
|
|
17133
17156
|
_client;
|
|
@@ -17150,7 +17173,8 @@ var LiveConfigProxy = class {
|
|
|
17150
17173
|
}
|
|
17151
17174
|
const values = target._currentValues();
|
|
17152
17175
|
if (target._model) {
|
|
17153
|
-
const
|
|
17176
|
+
const nested = _unflattenDotNotation(values);
|
|
17177
|
+
const instance = new target._model(nested);
|
|
17154
17178
|
return instance[prop];
|
|
17155
17179
|
}
|
|
17156
17180
|
return values[prop];
|
|
@@ -17312,6 +17336,11 @@ var ConfigClient = class {
|
|
|
17312
17336
|
/** @internal — resolves the management config sub-client used by lazy-init/refresh. */
|
|
17313
17337
|
_resolveManagement;
|
|
17314
17338
|
_configCache = {};
|
|
17339
|
+
/** Raw Config objects keyed by id, kept around so a single-config
|
|
17340
|
+
* change (WS event) can refetch one config and rebuild the resolved
|
|
17341
|
+
* cache for everyone (including descendants that inherit from it)
|
|
17342
|
+
* without a full re-list. Mirrors Python's `_raw_config_cache`. */
|
|
17343
|
+
_configStore = {};
|
|
17315
17344
|
_initialized = false;
|
|
17316
17345
|
_listeners = [];
|
|
17317
17346
|
/** @internal */
|
|
@@ -17420,12 +17449,15 @@ var ConfigClient = class {
|
|
|
17420
17449
|
}
|
|
17421
17450
|
const configs = await this._listConfigs();
|
|
17422
17451
|
const newCache = {};
|
|
17452
|
+
const newStore = {};
|
|
17423
17453
|
for (const cfg of configs) {
|
|
17424
17454
|
const chain = await cfg._buildChain(configs);
|
|
17425
17455
|
newCache[cfg.id] = resolveChain(chain, environment);
|
|
17456
|
+
newStore[cfg.id] = cfg;
|
|
17426
17457
|
}
|
|
17427
17458
|
const oldCache = this._configCache;
|
|
17428
17459
|
this._configCache = newCache;
|
|
17460
|
+
this._configStore = newStore;
|
|
17429
17461
|
this._diffAndFire(oldCache, newCache, "manual");
|
|
17430
17462
|
}
|
|
17431
17463
|
/**
|
|
@@ -17467,11 +17499,14 @@ var ConfigClient = class {
|
|
|
17467
17499
|
}
|
|
17468
17500
|
const configs = await this._listConfigs();
|
|
17469
17501
|
const cache = {};
|
|
17502
|
+
const store = {};
|
|
17470
17503
|
for (const cfg of configs) {
|
|
17471
17504
|
const chain = await cfg._buildChain(configs);
|
|
17472
17505
|
cache[cfg.id] = resolveChain(chain, environment);
|
|
17506
|
+
store[cfg.id] = cfg;
|
|
17473
17507
|
}
|
|
17474
17508
|
this._configCache = cache;
|
|
17509
|
+
this._configStore = store;
|
|
17475
17510
|
this._initialized = true;
|
|
17476
17511
|
if (this._getSharedWs) {
|
|
17477
17512
|
const ws = this._getSharedWs();
|
|
@@ -17485,11 +17520,14 @@ var ConfigClient = class {
|
|
|
17485
17520
|
if (this._initialized) return;
|
|
17486
17521
|
const configs = await this._listConfigs();
|
|
17487
17522
|
const cache = {};
|
|
17523
|
+
const store = {};
|
|
17488
17524
|
for (const cfg of configs) {
|
|
17489
17525
|
const chain = await cfg._buildChain(configs);
|
|
17490
17526
|
cache[cfg.id] = resolveChain(chain, environment);
|
|
17527
|
+
store[cfg.id] = cfg;
|
|
17491
17528
|
}
|
|
17492
17529
|
this._configCache = cache;
|
|
17530
|
+
this._configStore = store;
|
|
17493
17531
|
this._initialized = true;
|
|
17494
17532
|
}
|
|
17495
17533
|
/** @internal — get resolved config from cache. Used by LiveConfigProxy. */
|
|
@@ -17503,26 +17541,29 @@ var ConfigClient = class {
|
|
|
17503
17541
|
debug("websocket", `config_changed event received: ${JSON.stringify(data)}`);
|
|
17504
17542
|
const configKey = data.id;
|
|
17505
17543
|
if (!configKey) return;
|
|
17544
|
+
const environment = this._parent?._environment;
|
|
17545
|
+
if (!environment) return;
|
|
17506
17546
|
void this._fetchSingleConfig(configKey).then((newConfig) => {
|
|
17507
|
-
const
|
|
17508
|
-
if (
|
|
17509
|
-
|
|
17510
|
-
let newValues;
|
|
17511
|
-
if (newConfig !== null) {
|
|
17512
|
-
newValues = this._resolveConfigValues(newConfig, environment);
|
|
17547
|
+
const newStore = { ...this._configStore };
|
|
17548
|
+
if (newConfig === null) {
|
|
17549
|
+
delete newStore[configKey];
|
|
17513
17550
|
} else {
|
|
17514
|
-
|
|
17515
|
-
}
|
|
17516
|
-
const
|
|
17517
|
-
|
|
17518
|
-
|
|
17519
|
-
|
|
17520
|
-
|
|
17521
|
-
|
|
17522
|
-
|
|
17523
|
-
|
|
17524
|
-
}
|
|
17525
|
-
|
|
17551
|
+
newStore[configKey] = newConfig;
|
|
17552
|
+
}
|
|
17553
|
+
const allConfigs = Object.values(newStore);
|
|
17554
|
+
return Promise.all(
|
|
17555
|
+
allConfigs.map(async (cfg) => {
|
|
17556
|
+
const chain = await cfg._buildChain(allConfigs);
|
|
17557
|
+
return [cfg.id, resolveChain(chain, environment)];
|
|
17558
|
+
})
|
|
17559
|
+
).then((entries) => ({ entries, newStore }));
|
|
17560
|
+
}).then(({ entries, newStore }) => {
|
|
17561
|
+
const newCache = {};
|
|
17562
|
+
for (const [id, values] of entries) newCache[id] = values;
|
|
17563
|
+
const oldCache = this._configCache;
|
|
17564
|
+
this._configCache = newCache;
|
|
17565
|
+
this._configStore = newStore;
|
|
17566
|
+
this._diffAndFire(oldCache, newCache, "websocket");
|
|
17526
17567
|
}).catch((err) => {
|
|
17527
17568
|
debug(
|
|
17528
17569
|
"websocket",
|
|
@@ -17530,6 +17571,20 @@ var ConfigClient = class {
|
|
|
17530
17571
|
);
|
|
17531
17572
|
});
|
|
17532
17573
|
};
|
|
17574
|
+
/** Fetch a single config by key. Returns null if not found. @internal */
|
|
17575
|
+
async _fetchSingleConfig(key) {
|
|
17576
|
+
debug("api", `GET /api/v1/configs/${key}`);
|
|
17577
|
+
try {
|
|
17578
|
+
const result = await this._http.GET("/api/v1/configs/{id}", {
|
|
17579
|
+
params: { path: { id: key } }
|
|
17580
|
+
});
|
|
17581
|
+
if (!result.response.ok) return null;
|
|
17582
|
+
if (!result.data?.data) return null;
|
|
17583
|
+
return resourceToConfig(result.data.data);
|
|
17584
|
+
} catch {
|
|
17585
|
+
return null;
|
|
17586
|
+
}
|
|
17587
|
+
}
|
|
17533
17588
|
_handleConfigDeleted = (data) => {
|
|
17534
17589
|
debug("websocket", `config_deleted event received: ${JSON.stringify(data)}`);
|
|
17535
17590
|
const configKey = data.id;
|
|
@@ -17548,27 +17603,6 @@ var ConfigClient = class {
|
|
|
17548
17603
|
// ------------------------------------------------------------------
|
|
17549
17604
|
// Internal: change detection
|
|
17550
17605
|
// ------------------------------------------------------------------
|
|
17551
|
-
/** Fetch a single config by key. Returns null if not found. @internal */
|
|
17552
|
-
async _fetchSingleConfig(key) {
|
|
17553
|
-
debug("api", `GET /api/v1/configs/${key}`);
|
|
17554
|
-
try {
|
|
17555
|
-
const result = await this._http.GET("/api/v1/configs/{id}", {
|
|
17556
|
-
params: { path: { id: key } }
|
|
17557
|
-
});
|
|
17558
|
-
if (!result.response.ok) return null;
|
|
17559
|
-
if (!result.data?.data) return null;
|
|
17560
|
-
return resourceToConfig(result.data.data);
|
|
17561
|
-
} catch {
|
|
17562
|
-
return null;
|
|
17563
|
-
}
|
|
17564
|
-
}
|
|
17565
|
-
/** Resolve a config's values for an environment (no parent chain). @internal */
|
|
17566
|
-
_resolveConfigValues(config, environment) {
|
|
17567
|
-
const base = config.items ?? {};
|
|
17568
|
-
const envEntry = config.environments?.[environment];
|
|
17569
|
-
if (!envEntry?.values) return { ...base };
|
|
17570
|
-
return { ...base, ...envEntry.values };
|
|
17571
|
-
}
|
|
17572
17606
|
/** @internal */
|
|
17573
17607
|
_diffAndFire(oldCache, newCache, source) {
|
|
17574
17608
|
const allConfigKeys = /* @__PURE__ */ new Set([...Object.keys(oldCache), ...Object.keys(newCache)]);
|