@shop-os/modelkit 0.2.0 → 0.2.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/CHANGELOG.md +32 -0
- package/dist/catalog.cjs +73 -73
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +12 -3
- package/dist/catalog.d.ts +12 -3
- package/dist/catalog.js +73 -73
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +115 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +114 -84
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,36 @@ header in the release PR.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.2.2] - 2026-09-15
|
|
13
|
+
|
|
14
|
+
Option audit against provider docs, limited to options a product surface sets.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- Veo 3.1, 3.1 Fast and 3.1 Lite accept `seed` (sent as `config.seed`).
|
|
18
|
+
- Seedream 5.0 Pro accepts `outputFormat` png/jpeg (sent as `output_format`; webp is coerced to png with a warning).
|
|
19
|
+
- Gemini 3 image rows declare `references.images: 14`, the provider cap.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
- `liveCatalog` and the prime state are one process-wide singleton (on `globalThis`). The root and `./catalog` bundles each carried their own copy, so a server that primed through the root entry still served the snapshot to code importing `@shop-os/modelkit/catalog`.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- gpt-image-2.5-sunburst/flare `qualityOptions` add `xhigh` and `max`.
|
|
26
|
+
- Veo 3.1 Fast and Lite durations add 6 s. Veo 3.1 Lite drops `references` (not supported for Lite).
|
|
27
|
+
- Gemini Omni rows allow 3 reference videos (was 1).
|
|
28
|
+
- Seedance rows declare `ratioIgnoredWith: ["firstFrame", "sourceVideo"]` to match the adapter.
|
|
29
|
+
- kling-v3-omni-video aspect ratios are 16:9, 9:16, 1:1, adaptive (provider list).
|
|
30
|
+
- seedream-4.5 drops the 1K tier (provider minimum 2K). gemini-2.5-flash-image is 1K only. muse-image-1.0 drops 4:5 and 5:4.
|
|
31
|
+
- qwen-image-2-pro no longer requires a reference image.
|
|
32
|
+
- Prodia nano-banana rows drop `seed` (the adapter never sent it).
|
|
33
|
+
|
|
34
|
+
## [0.2.1] - 2026-09-15
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
- `gpt-image-2`, `gpt-image-2.5-sunburst` and `gpt-image-2.5-flare` declare `outputFormat`; the `openai-image` adapter sends `output_format` (png or jpeg) and labels the result mime to match.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- `outputFormat: "webp"` on GPT image models is coerced to png with an `option_ignored` warning: the API returns PNG bytes for webp (openai/openai-node#1850).
|
|
41
|
+
|
|
12
42
|
## [0.2.0] - 2026-09-14
|
|
13
43
|
|
|
14
44
|
### Added
|
|
@@ -210,6 +240,8 @@ First publish, renamed from `@shop-os/model-sdk`.
|
|
|
210
240
|
type, one usage event with the canonical id.
|
|
211
241
|
|
|
212
242
|
[Unreleased]: https://github.com/Shop-OS/shopos-backend-ts/compare/modelkit-0.2.0...dev
|
|
243
|
+
[0.2.2]: https://github.com/Shop-OS/shopos-backend-ts/compare/modelkit-0.2.1...modelkit-0.2.2
|
|
244
|
+
[0.2.1]: https://github.com/Shop-OS/shopos-backend-ts/compare/modelkit-0.2.0...modelkit-0.2.1
|
|
213
245
|
[0.2.0]: https://github.com/Shop-OS/shopos-backend-ts/compare/modelkit-0.1.11...modelkit-0.2.0
|
|
214
246
|
[0.1.11]: https://github.com/Shop-OS/shopos-backend-ts/compare/f0981d9b9...bb3b16354
|
|
215
247
|
[0.1.10]: https://github.com/Shop-OS/shopos-backend-ts/compare/f17e822e2...f0981d9b9
|
package/dist/catalog.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(catalog_entry_exports, {
|
|
|
32
32
|
VIDEO_MODELS: () => VIDEO_MODELS,
|
|
33
33
|
isModelKitError: () => isModelKitError,
|
|
34
34
|
liveCatalog: () => liveCatalog,
|
|
35
|
+
liveState: () => liveState,
|
|
35
36
|
nearestAspectRatio: () => nearestAspectRatio,
|
|
36
37
|
primeCatalog: () => primeCatalog,
|
|
37
38
|
resetLiveCatalog: () => resetLiveCatalog,
|
|
@@ -162,7 +163,7 @@ var GEMINI_RATIOS = [
|
|
|
162
163
|
"5:4",
|
|
163
164
|
"adaptive"
|
|
164
165
|
];
|
|
165
|
-
function geminiImage(id, label, aliases, sizes, display, exposure) {
|
|
166
|
+
function geminiImage(id, label, aliases, sizes, display, exposure, references) {
|
|
166
167
|
const model = {
|
|
167
168
|
id,
|
|
168
169
|
aliases,
|
|
@@ -175,7 +176,8 @@ function geminiImage(id, label, aliases, sizes, display, exposure) {
|
|
|
175
176
|
constraints: {
|
|
176
177
|
aspectRatios: [...GEMINI_RATIOS],
|
|
177
178
|
sizes,
|
|
178
|
-
supports: ["safetySettings", "temperature"]
|
|
179
|
+
supports: ["safetySettings", "temperature"],
|
|
180
|
+
...references ? { references } : {}
|
|
179
181
|
},
|
|
180
182
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
181
183
|
usage: { ...IMAGE_USAGE, slug: "gemini" },
|
|
@@ -195,7 +197,8 @@ var IMAGE_MODELS = [
|
|
|
195
197
|
description: "Create stunning, production-quality visuals with exceptional realism, detail, and typography. Best for campaigns, e-commerce, product photography, and hero creatives.",
|
|
196
198
|
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
197
199
|
},
|
|
198
|
-
"catalog"
|
|
200
|
+
"catalog",
|
|
201
|
+
{ images: 14 }
|
|
199
202
|
),
|
|
200
203
|
geminiImage(
|
|
201
204
|
"gemini-3.1-flash-image-preview",
|
|
@@ -208,7 +211,8 @@ var IMAGE_MODELS = [
|
|
|
208
211
|
description: "Generate high-quality images at speed. Perfect for brainstorming, moodboards, concept testing, creative exploration, and large batch workflows.",
|
|
209
212
|
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
210
213
|
},
|
|
211
|
-
"catalog"
|
|
214
|
+
"catalog",
|
|
215
|
+
{ images: 14 }
|
|
212
216
|
),
|
|
213
217
|
geminiImage(
|
|
214
218
|
"gemini-3.1-flash-lite-image",
|
|
@@ -220,14 +224,15 @@ var IMAGE_MODELS = [
|
|
|
220
224
|
description: "The fastest and most affordable image model. Ideal for rapid drafts, bulk exploration, and iterative concept testing at 1K resolution.",
|
|
221
225
|
logo: "https://d31vvfpk2ppdyq.cloudfront.net/assets/image/192485d2-a76a-4657-9c06-930b2c70badd_compressed.png"
|
|
222
226
|
},
|
|
223
|
-
"catalog"
|
|
227
|
+
"catalog",
|
|
228
|
+
{ images: 14 }
|
|
224
229
|
),
|
|
225
230
|
// trigger-workflows validates 1K only; pricing seeds 2K/4K rows so allow all three.
|
|
226
231
|
geminiImage(
|
|
227
232
|
"gemini-2.5-flash-image",
|
|
228
233
|
"Gemini 2.5 Flash Image",
|
|
229
234
|
[],
|
|
230
|
-
["1K"
|
|
235
|
+
["1K"],
|
|
231
236
|
{
|
|
232
237
|
provider: "google",
|
|
233
238
|
description: "Nano Banana (legacy Gemini 2.5 Flash Image) native image generation and editing model for high-volume, low-latency creative workflows."
|
|
@@ -258,7 +263,7 @@ var IMAGE_MODELS = [
|
|
|
258
263
|
sizes: ["1K", "2K", "4K"],
|
|
259
264
|
qualityOptions: ["auto", "low", "medium", "high"],
|
|
260
265
|
references: { images: 16 },
|
|
261
|
-
supports: ["quality", "count"]
|
|
266
|
+
supports: ["quality", "count", "outputFormat"]
|
|
262
267
|
},
|
|
263
268
|
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
264
269
|
usage: { ...IMAGE_USAGE, slug: "gpt" },
|
|
@@ -278,7 +283,7 @@ var IMAGE_MODELS = [
|
|
|
278
283
|
adapter: "openai-image",
|
|
279
284
|
providerModelId: "gpt-image-2.5-sunburst",
|
|
280
285
|
lifecycle: "active",
|
|
281
|
-
exposure: "
|
|
286
|
+
exposure: "catalog",
|
|
282
287
|
constraints: {
|
|
283
288
|
exactSizes: {
|
|
284
289
|
"1:1": "1024x1024",
|
|
@@ -291,9 +296,9 @@ var IMAGE_MODELS = [
|
|
|
291
296
|
},
|
|
292
297
|
aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
|
|
293
298
|
sizes: ["1K", "2K", "4K"],
|
|
294
|
-
qualityOptions: ["auto", "low", "medium", "high"],
|
|
299
|
+
qualityOptions: ["auto", "low", "medium", "high", "xhigh", "max"],
|
|
295
300
|
references: { images: 16 },
|
|
296
|
-
supports: ["quality", "count"]
|
|
301
|
+
supports: ["quality", "count", "outputFormat"]
|
|
297
302
|
},
|
|
298
303
|
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
299
304
|
usage: { ...IMAGE_USAGE },
|
|
@@ -312,7 +317,7 @@ var IMAGE_MODELS = [
|
|
|
312
317
|
adapter: "openai-image",
|
|
313
318
|
providerModelId: "gpt-image-2.5-flare",
|
|
314
319
|
lifecycle: "active",
|
|
315
|
-
exposure: "
|
|
320
|
+
exposure: "catalog",
|
|
316
321
|
constraints: {
|
|
317
322
|
exactSizes: {
|
|
318
323
|
"1:1": "1024x1024",
|
|
@@ -325,9 +330,9 @@ var IMAGE_MODELS = [
|
|
|
325
330
|
},
|
|
326
331
|
aspectRatios: ["1:1", "3:2", "2:3", "16:9", "9:16", "4:5", "5:4", "adaptive"],
|
|
327
332
|
sizes: ["1K", "2K", "4K"],
|
|
328
|
-
qualityOptions: ["auto", "low", "medium", "high"],
|
|
333
|
+
qualityOptions: ["auto", "low", "medium", "high", "xhigh", "max"],
|
|
329
334
|
references: { images: 16 },
|
|
330
|
-
supports: ["quality", "count"]
|
|
335
|
+
supports: ["quality", "count", "outputFormat"]
|
|
331
336
|
},
|
|
332
337
|
defaults: { size: "1K", aspectRatio: "adaptive", quality: "auto" },
|
|
333
338
|
usage: { ...IMAGE_USAGE },
|
|
@@ -357,8 +362,6 @@ var IMAGE_MODELS = [
|
|
|
357
362
|
"2:3",
|
|
358
363
|
"3:4",
|
|
359
364
|
"9:16",
|
|
360
|
-
"4:5",
|
|
361
|
-
"5:4",
|
|
362
365
|
"9:21",
|
|
363
366
|
"adaptive"
|
|
364
367
|
],
|
|
@@ -390,7 +393,7 @@ var IMAGE_MODELS = [
|
|
|
390
393
|
references: { images: 10 },
|
|
391
394
|
// Ark's Images API has no output-format, quality or count field; only
|
|
392
395
|
// the seed is forwarded, so anything else must warn, not vanish.
|
|
393
|
-
supports: ["seed"]
|
|
396
|
+
supports: ["seed", "outputFormat"]
|
|
394
397
|
},
|
|
395
398
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
396
399
|
usage: { ...IMAGE_USAGE },
|
|
@@ -426,7 +429,7 @@ var IMAGE_MODELS = [
|
|
|
426
429
|
"21:9",
|
|
427
430
|
"9:21"
|
|
428
431
|
],
|
|
429
|
-
sizes: ["
|
|
432
|
+
sizes: ["2K", "4K"],
|
|
430
433
|
references: { images: 10 },
|
|
431
434
|
supports: ["seed"]
|
|
432
435
|
},
|
|
@@ -478,7 +481,7 @@ var IMAGE_MODELS = [
|
|
|
478
481
|
aspectRatios: ["1:1", "2:3", "3:2", "4:3", "3:4", "4:5", "5:4", "9:16", "16:9", "21:9"],
|
|
479
482
|
sizes: ["1K", "2K", "4K"],
|
|
480
483
|
requires: ["references"],
|
|
481
|
-
supports: [
|
|
484
|
+
supports: []
|
|
482
485
|
},
|
|
483
486
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
484
487
|
usage: { ...IMAGE_USAGE },
|
|
@@ -503,7 +506,7 @@ var IMAGE_MODELS = [
|
|
|
503
506
|
aspectRatios: ["1:1", "2:3", "3:4", "4:3", "9:16", "16:9", "21:9"],
|
|
504
507
|
sizes: ["1K"],
|
|
505
508
|
requires: ["references"],
|
|
506
|
-
supports: [
|
|
509
|
+
supports: []
|
|
507
510
|
},
|
|
508
511
|
defaults: { size: "1K", aspectRatio: "1:1" },
|
|
509
512
|
usage: { ...IMAGE_USAGE },
|
|
@@ -555,7 +558,6 @@ var IMAGE_MODELS = [
|
|
|
555
558
|
aspectRatios: ["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"],
|
|
556
559
|
sizes: [],
|
|
557
560
|
references: { images: 1 },
|
|
558
|
-
requires: ["references"],
|
|
559
561
|
supports: []
|
|
560
562
|
},
|
|
561
563
|
defaults: { aspectRatio: "1:1" },
|
|
@@ -1274,7 +1276,7 @@ var VIDEO_MODELS = [
|
|
|
1274
1276
|
resolutions: ["720p", "1080p", "4k"],
|
|
1275
1277
|
durations: [8],
|
|
1276
1278
|
references: { images: 3 },
|
|
1277
|
-
supports: ["lastFrame"]
|
|
1279
|
+
supports: ["lastFrame", "seed"]
|
|
1278
1280
|
},
|
|
1279
1281
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
1280
1282
|
usage: { ...VIDEO_USAGE, slug: "veo" },
|
|
@@ -1302,9 +1304,9 @@ var VIDEO_MODELS = [
|
|
|
1302
1304
|
constraints: {
|
|
1303
1305
|
aspectRatios: [...OMNI_RATIOS],
|
|
1304
1306
|
resolutions: ["720p", "1080p", "4k"],
|
|
1305
|
-
durations: [4, 8],
|
|
1307
|
+
durations: [4, 6, 8],
|
|
1306
1308
|
references: { images: 3 },
|
|
1307
|
-
supports: ["lastFrame"]
|
|
1309
|
+
supports: ["lastFrame", "seed"]
|
|
1308
1310
|
},
|
|
1309
1311
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
1310
1312
|
usage: { ...VIDEO_USAGE },
|
|
@@ -1331,9 +1333,8 @@ var VIDEO_MODELS = [
|
|
|
1331
1333
|
constraints: {
|
|
1332
1334
|
aspectRatios: [...OMNI_RATIOS],
|
|
1333
1335
|
resolutions: ["720p", "1080p"],
|
|
1334
|
-
durations: [4, 8],
|
|
1335
|
-
|
|
1336
|
-
supports: ["lastFrame"]
|
|
1336
|
+
durations: [4, 6, 8],
|
|
1337
|
+
supports: ["lastFrame", "seed"]
|
|
1337
1338
|
},
|
|
1338
1339
|
defaults: { durationSeconds: 8, resolution: "720p", aspectRatio: "16:9" },
|
|
1339
1340
|
usage: { ...VIDEO_USAGE },
|
|
@@ -1365,7 +1366,7 @@ var VIDEO_MODELS = [
|
|
|
1365
1366
|
// reference clip keeps its own framing.
|
|
1366
1367
|
aspectRatios: [...OMNI_RATIOS],
|
|
1367
1368
|
durations: [3, 4, 5, 6, 7, 8, 9, 10],
|
|
1368
|
-
references: { images: 6, videos:
|
|
1369
|
+
references: { images: 6, videos: 3 },
|
|
1369
1370
|
supports: []
|
|
1370
1371
|
},
|
|
1371
1372
|
defaults: {},
|
|
@@ -1391,7 +1392,7 @@ var VIDEO_MODELS = [
|
|
|
1391
1392
|
aspectRatios: [...OMNI_RATIOS],
|
|
1392
1393
|
resolutions: ["360p", "720p", "1080p", "4k"],
|
|
1393
1394
|
durations: [3, 4, 5, 6, 7, 8, 9, 10],
|
|
1394
|
-
references: { images: 6, videos:
|
|
1395
|
+
references: { images: 6, videos: 3 },
|
|
1395
1396
|
supports: []
|
|
1396
1397
|
},
|
|
1397
1398
|
defaults: {},
|
|
@@ -1420,7 +1421,7 @@ var VIDEO_MODELS = [
|
|
|
1420
1421
|
durations: { min: 4, max: 15 },
|
|
1421
1422
|
durationPresets: [4, 6, 8, 10, 12, 15],
|
|
1422
1423
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
1423
|
-
ratioIgnoredWith: ["firstFrame"],
|
|
1424
|
+
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
1424
1425
|
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
1425
1426
|
},
|
|
1426
1427
|
defaults: {
|
|
@@ -1452,7 +1453,7 @@ var VIDEO_MODELS = [
|
|
|
1452
1453
|
resolutions: ["480p", "720p"],
|
|
1453
1454
|
durations: { min: 4, max: 15 },
|
|
1454
1455
|
references: { images: 9, videos: 3, audios: 3, audioOnly: false },
|
|
1455
|
-
ratioIgnoredWith: ["firstFrame"],
|
|
1456
|
+
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
1456
1457
|
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
1457
1458
|
},
|
|
1458
1459
|
defaults: {
|
|
@@ -1485,7 +1486,7 @@ var VIDEO_MODELS = [
|
|
|
1485
1486
|
resolutions: ["480p", "720p", "1080p"],
|
|
1486
1487
|
durations: { min: 4, max: 30 },
|
|
1487
1488
|
references: { images: 30, videos: 10, audios: 10 },
|
|
1488
|
-
ratioIgnoredWith: ["firstFrame"],
|
|
1489
|
+
ratioIgnoredWith: ["firstFrame", "sourceVideo"],
|
|
1489
1490
|
supports: ["generateAudio", "seed", "lastFrame", "watermark"]
|
|
1490
1491
|
},
|
|
1491
1492
|
defaults: {
|
|
@@ -1604,18 +1605,7 @@ var VIDEO_MODELS = [
|
|
|
1604
1605
|
lifecycle: "active",
|
|
1605
1606
|
exposure: "catalog",
|
|
1606
1607
|
constraints: {
|
|
1607
|
-
aspectRatios: [
|
|
1608
|
-
"1:1",
|
|
1609
|
-
"16:9",
|
|
1610
|
-
"9:16",
|
|
1611
|
-
"4:3",
|
|
1612
|
-
"3:4",
|
|
1613
|
-
"3:2",
|
|
1614
|
-
"2:3",
|
|
1615
|
-
"21:9",
|
|
1616
|
-
"4:5",
|
|
1617
|
-
"adaptive"
|
|
1618
|
-
],
|
|
1608
|
+
aspectRatios: [...KLING_RATIOS],
|
|
1619
1609
|
resolutions: ["720p", "1080p"],
|
|
1620
1610
|
durations: { min: 3, max: 15 },
|
|
1621
1611
|
references: { images: 7 },
|
|
@@ -2077,13 +2067,18 @@ var CatalogSchema = import_zod.z.array(CatalogModelSchemaBase).superRefine((rows
|
|
|
2077
2067
|
});
|
|
2078
2068
|
|
|
2079
2069
|
// src/catalog/live.ts
|
|
2080
|
-
var
|
|
2070
|
+
var KEY = /* @__PURE__ */ Symbol.for("@shop-os/modelkit/live-catalog");
|
|
2071
|
+
var store = globalThis;
|
|
2072
|
+
var liveState = store[KEY] ??= {
|
|
2073
|
+
catalog: new Catalog(MODELS),
|
|
2074
|
+
memo: void 0,
|
|
2075
|
+
timer: void 0,
|
|
2076
|
+
revision: void 0,
|
|
2077
|
+
origin: "snapshot"
|
|
2078
|
+
};
|
|
2079
|
+
var liveCatalog = liveState.catalog;
|
|
2081
2080
|
|
|
2082
2081
|
// src/catalog/load.ts
|
|
2083
|
-
var memo;
|
|
2084
|
-
var timer;
|
|
2085
|
-
var revision;
|
|
2086
|
-
var origin = "snapshot";
|
|
2087
2082
|
function rowCount() {
|
|
2088
2083
|
return liveCatalog.list({ lifecycle: ["active", "deprecated", "retired"] }).length;
|
|
2089
2084
|
}
|
|
@@ -2113,7 +2108,7 @@ function logPrimed(logger, result) {
|
|
|
2113
2108
|
async function fetchRemote(source, logger) {
|
|
2114
2109
|
const fetchImpl = source.fetch ?? globalThis.fetch;
|
|
2115
2110
|
const headers = authHeaders(source.auth);
|
|
2116
|
-
if (revision !== void 0) headers["If-None-Match"] = `"${revision}"`;
|
|
2111
|
+
if (liveState.revision !== void 0) headers["If-None-Match"] = `"${liveState.revision}"`;
|
|
2117
2112
|
const res = await fetchImpl(`${source.baseUrl}/models/catalog`, {
|
|
2118
2113
|
headers,
|
|
2119
2114
|
signal: AbortSignal.timeout(source.timeoutMs ?? 1e4)
|
|
@@ -2137,16 +2132,16 @@ async function prime(source, logger) {
|
|
|
2137
2132
|
try {
|
|
2138
2133
|
const fetched = await fetchRemote(source, logger);
|
|
2139
2134
|
if ("kept" in fetched) {
|
|
2140
|
-
const result2 = { origin, rowCount: rowCount() };
|
|
2141
|
-
if (revision !== void 0) result2.revision = revision;
|
|
2135
|
+
const result2 = { origin: liveState.origin, rowCount: rowCount() };
|
|
2136
|
+
if (liveState.revision !== void 0) result2.revision = liveState.revision;
|
|
2142
2137
|
logPrimed(logger, result2);
|
|
2143
2138
|
return result2;
|
|
2144
2139
|
}
|
|
2145
2140
|
liveCatalog.replace(fetched.rows);
|
|
2146
|
-
origin = "remote";
|
|
2147
|
-
revision = fetched.revision;
|
|
2141
|
+
liveState.origin = "remote";
|
|
2142
|
+
liveState.revision = fetched.revision;
|
|
2148
2143
|
await writeCache(source, logger, fetched.rows, fetched.revision);
|
|
2149
|
-
const result = { origin, rowCount: rowCount() };
|
|
2144
|
+
const result = { origin: liveState.origin, rowCount: rowCount() };
|
|
2150
2145
|
if (fetched.revision !== void 0) result.revision = fetched.revision;
|
|
2151
2146
|
logPrimed(logger, result);
|
|
2152
2147
|
return result;
|
|
@@ -2158,19 +2153,23 @@ async function prime(source, logger) {
|
|
|
2158
2153
|
if (!cached) throw new Error("no cached catalog");
|
|
2159
2154
|
const { rows, revision: rev } = parseEnvelope(JSON.parse(cached));
|
|
2160
2155
|
liveCatalog.replace(rows);
|
|
2161
|
-
origin = "last-good";
|
|
2162
|
-
revision = rev;
|
|
2163
|
-
const result = {
|
|
2156
|
+
liveState.origin = "last-good";
|
|
2157
|
+
liveState.revision = rev;
|
|
2158
|
+
const result = {
|
|
2159
|
+
origin: liveState.origin,
|
|
2160
|
+
rowCount: rowCount(),
|
|
2161
|
+
error
|
|
2162
|
+
};
|
|
2164
2163
|
if (rev !== void 0) result.revision = rev;
|
|
2165
2164
|
logPrimed(logger, result);
|
|
2166
2165
|
return result;
|
|
2167
2166
|
} catch (cacheErr) {
|
|
2168
2167
|
logger.warn("[modelkit] catalog cache failed, using snapshot", cacheErr);
|
|
2169
2168
|
liveCatalog.replace([...MODELS]);
|
|
2170
|
-
origin = "snapshot";
|
|
2171
|
-
revision = void 0;
|
|
2169
|
+
liveState.origin = "snapshot";
|
|
2170
|
+
liveState.revision = void 0;
|
|
2172
2171
|
const result = {
|
|
2173
|
-
origin,
|
|
2172
|
+
origin: liveState.origin,
|
|
2174
2173
|
rowCount: rowCount(),
|
|
2175
2174
|
error
|
|
2176
2175
|
};
|
|
@@ -2184,35 +2183,36 @@ async function refresh(source, logger) {
|
|
|
2184
2183
|
const fetched = await fetchRemote(source, logger);
|
|
2185
2184
|
if ("kept" in fetched) return;
|
|
2186
2185
|
liveCatalog.replace(fetched.rows);
|
|
2187
|
-
origin = "remote";
|
|
2188
|
-
revision = fetched.revision;
|
|
2186
|
+
liveState.origin = "remote";
|
|
2187
|
+
liveState.revision = fetched.revision;
|
|
2189
2188
|
await writeCache(source, logger, fetched.rows, fetched.revision);
|
|
2190
2189
|
} catch (err) {
|
|
2191
2190
|
logger.warn("[modelkit] catalog refresh failed, keeping current rows", err);
|
|
2192
2191
|
}
|
|
2193
2192
|
}
|
|
2194
2193
|
function primeCatalog(source) {
|
|
2194
|
+
const memo = liveState.memo;
|
|
2195
2195
|
if (memo) return memo;
|
|
2196
2196
|
const logger = source.logger ?? console;
|
|
2197
|
-
memo = prime(source, logger).then((result) => {
|
|
2197
|
+
liveState.memo = prime(source, logger).then((result) => {
|
|
2198
2198
|
const ttlMs = source.ttlMs ?? 3e5;
|
|
2199
|
-
if (ttlMs > 0 && timer === void 0) {
|
|
2200
|
-
timer = setInterval(() => void refresh(source, logger), ttlMs);
|
|
2201
|
-
const maybeUnref = timer;
|
|
2199
|
+
if (ttlMs > 0 && liveState.timer === void 0) {
|
|
2200
|
+
liveState.timer = setInterval(() => void refresh(source, logger), ttlMs);
|
|
2201
|
+
const maybeUnref = liveState.timer;
|
|
2202
2202
|
maybeUnref.unref?.();
|
|
2203
2203
|
}
|
|
2204
2204
|
return result;
|
|
2205
2205
|
});
|
|
2206
|
-
return memo;
|
|
2206
|
+
return liveState.memo;
|
|
2207
2207
|
}
|
|
2208
2208
|
function resetLiveCatalog() {
|
|
2209
|
-
if (timer !== void 0) {
|
|
2210
|
-
clearInterval(timer);
|
|
2211
|
-
timer = void 0;
|
|
2209
|
+
if (liveState.timer !== void 0) {
|
|
2210
|
+
clearInterval(liveState.timer);
|
|
2211
|
+
liveState.timer = void 0;
|
|
2212
2212
|
}
|
|
2213
|
-
memo = void 0;
|
|
2214
|
-
revision = void 0;
|
|
2215
|
-
origin = "snapshot";
|
|
2213
|
+
liveState.memo = void 0;
|
|
2214
|
+
liveState.revision = void 0;
|
|
2215
|
+
liveState.origin = "snapshot";
|
|
2216
2216
|
liveCatalog.replace([...MODELS]);
|
|
2217
2217
|
}
|
|
2218
2218
|
|