@rslsp1/fa-app-tools 6.1.0 → 7.2.0

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/szenen.js CHANGED
@@ -54,6 +54,9 @@ __export(szenen_exports, {
54
54
  SZENEN_EVENT_TYPES: () => SZENEN_EVENT_TYPES,
55
55
  SZENEN_ITEM_PREFIX: () => SZENEN_ITEM_PREFIX,
56
56
  SZENEN_SCHEMAS: () => SZENEN_SCHEMAS,
57
+ SZENEN_SNAPSHOT_FILE: () => SZENEN_SNAPSHOT_FILE,
58
+ SZENEN_SNAPSHOT_PREFIX: () => SZENEN_SNAPSHOT_PREFIX,
59
+ SZENEN_SNAPSHOT_SCHEMA_VERSION: () => SZENEN_SNAPSHOT_SCHEMA_VERSION,
57
60
  SzenenView: () => SzenenView,
58
61
  UNCHECKED_PUBLISH_RULES: () => UNCHECKED_PUBLISH_RULES,
59
62
  UPLOAD_MAX_BYTES: () => UPLOAD_MAX_BYTES,
@@ -66,6 +69,7 @@ __export(szenen_exports, {
66
69
  buildDerivationSystemInstruction: () => buildSystemInstruction2,
67
70
  buildDerivationUserPrompt: () => buildUserPrompt2,
68
71
  buildSystemInstruction: () => buildSystemInstruction,
72
+ buildSzenenSnapshot: () => buildSzenenSnapshot,
69
73
  buildUserPrompt: () => buildUserPrompt,
70
74
  buildVersionDag: () => buildVersionDag,
71
75
  callOptional: () => callOptional,
@@ -156,6 +160,7 @@ __export(szenen_exports, {
156
160
  isOk: () => isOk,
157
161
  isProjectionCurrent: () => isProjectionCurrent,
158
162
  isSzenenItemId: () => isSzenenItemId,
163
+ istSzenenSnapshotDatei: () => istSzenenSnapshotDatei,
159
164
  istZipDatei: () => istZipDatei,
160
165
  itemIdForRun: () => itemIdForRun,
161
166
  ladeVorschauen: () => ladeVorschauen,
@@ -163,6 +168,7 @@ __export(szenen_exports, {
163
168
  linkFor: () => linkFor,
164
169
  locatorTeile: () => locatorTeile,
165
170
  logRevisionOf: () => logRevisionOf,
171
+ mergeSnapshotAndPending: () => mergeSnapshotAndPending,
166
172
  mergeSzenenBatchOrigin: () => mergeSzenenBatchOrigin,
167
173
  mitDefaultVorlage: () => mitDefaultVorlage,
168
174
  noticeFor: () => noticeFor,
@@ -171,6 +177,7 @@ __export(szenen_exports, {
171
177
  parseDerivationResponse: () => parseDerivationResponse,
172
178
  parseRunResponse: () => parseRunResponse,
173
179
  parseSeedListe: () => parseSeedListe,
180
+ parseSzenenSnapshot: () => parseSzenenSnapshot,
174
181
  preferredHeadRevisionOf: () => preferredHeadRevisionOf,
175
182
  preferredVersionId: () => preferredVersionId,
176
183
  promptDiagnosticsOf: () => promptDiagnosticsOf,
@@ -198,6 +205,7 @@ __export(szenen_exports, {
198
205
  selectableTargetModels: () => selectableTargetModels,
199
206
  showChain: () => showChain,
200
207
  simulatedAnswerFor: () => simulatedAnswerFor,
208
+ szenenSnapshotFilename: () => szenenSnapshotFilename,
201
209
  totalModelCalls: () => totalModelCalls,
202
210
  typAusBytes: () => typAusBytes,
203
211
  unclassifiedPublishRules: () => unclassifiedPublishRules,
@@ -8291,6 +8299,85 @@ function bildEndungFuer(mimeType) {
8291
8299
  return "jpg";
8292
8300
  }
8293
8301
 
8302
+ // src/lib/szenen/szenenSnapshot.ts
8303
+ var SZENEN_SNAPSHOT_SCHEMA_VERSION = 1;
8304
+ var SZENEN_SNAPSHOT_PREFIX = "szenen-state-";
8305
+ var SZENEN_SNAPSHOT_FILE = "szenen-state.json";
8306
+ function szenenSnapshotFilename(maxTs) {
8307
+ const stamp = new Date(maxTs).toISOString().replace(/:/g, "-").replace(".", "-");
8308
+ return `${SZENEN_SNAPSHOT_PREFIX}${stamp}.json`;
8309
+ }
8310
+ function istSzenenSnapshotDatei(name) {
8311
+ return name.startsWith(SZENEN_SNAPSHOT_PREFIX) && name.endsWith(".json");
8312
+ }
8313
+ var maxTsOf = (events) => {
8314
+ let max = 0;
8315
+ for (const event of events) if (event.ts > max) max = event.ts;
8316
+ return max;
8317
+ };
8318
+ function buildSzenenSnapshot(base, neue, neuePfade = []) {
8319
+ const events = [...base?.events ?? [], ...neue];
8320
+ const paths = [...base?.consumed.paths ?? [], ...neuePfade.map(basisname)];
8321
+ return {
8322
+ schema_version: SZENEN_SNAPSHOT_SCHEMA_VERSION,
8323
+ consumed: { count: events.length, max_ts: maxTsOf(events), paths },
8324
+ events
8325
+ };
8326
+ }
8327
+ function basisname(pfad) {
8328
+ return pfad.split("/").pop() ?? pfad;
8329
+ }
8330
+ function aufgenommeneDateien(snapshot) {
8331
+ return new Set(snapshot ? snapshot.consumed.paths : []);
8332
+ }
8333
+ function parseSzenenSnapshot(raw, herkunft) {
8334
+ if (!raw || typeof raw !== "object") {
8335
+ throw new Error(`Szenen-Snapshot ${herkunft}: kein Objekt, sondern ${typeof raw}.`);
8336
+ }
8337
+ const obj = raw;
8338
+ if (obj.schema_version !== SZENEN_SNAPSHOT_SCHEMA_VERSION) {
8339
+ throw new Error(
8340
+ `Szenen-Snapshot ${herkunft}: schema_version ${String(obj.schema_version)} wird nicht gelesen, erwartet ${SZENEN_SNAPSHOT_SCHEMA_VERSION}.`
8341
+ );
8342
+ }
8343
+ if (!Array.isArray(obj.events)) {
8344
+ throw new Error(`Szenen-Snapshot ${herkunft}: "events" fehlt oder ist kein Array.`);
8345
+ }
8346
+ const events = obj.events;
8347
+ for (const [i, event] of events.entries()) {
8348
+ if (!event || typeof event.type !== "string" || typeof event.ts !== "number") {
8349
+ throw new Error(
8350
+ `Szenen-Snapshot ${herkunft}: Ereignis ${i} hat keinen Typ oder keinen Zeitstempel.`
8351
+ );
8352
+ }
8353
+ }
8354
+ const consumed = obj.consumed;
8355
+ if (!consumed || typeof consumed.count !== "number" || typeof consumed.max_ts !== "number") {
8356
+ throw new Error(`Szenen-Snapshot ${herkunft}: "consumed" fehlt oder ist unvollstaendig.`);
8357
+ }
8358
+ if (!Array.isArray(consumed.paths)) {
8359
+ throw new Error(
8360
+ `Szenen-Snapshot ${herkunft}: "consumed.paths" fehlt. Ohne die aufgenommenen Dateinamen laesst sich nicht entscheiden, welche Datei in events/ noch aussteht.`
8361
+ );
8362
+ }
8363
+ if (consumed.count !== events.length) {
8364
+ throw new Error(
8365
+ `Szenen-Snapshot ${herkunft}: consumed.count ${consumed.count} passt nicht zu ${events.length} Ereignis(sen) in der Datei \u2014 die Datei ist unvollstaendig.`
8366
+ );
8367
+ }
8368
+ const echt = maxTsOf(events);
8369
+ if (consumed.max_ts !== echt) {
8370
+ throw new Error(
8371
+ `Szenen-Snapshot ${herkunft}: consumed.max_ts ${consumed.max_ts} passt nicht zum groessten Zeitstempel ${echt} in der Datei.`
8372
+ );
8373
+ }
8374
+ return { schema_version: SZENEN_SNAPSHOT_SCHEMA_VERSION, consumed, events };
8375
+ }
8376
+ function mergeSnapshotAndPending(snapshot, pending, bereitsImSnapshot = 0) {
8377
+ if (!snapshot) return { events: pending, bereitsImSnapshot };
8378
+ return { events: [...snapshot.events, ...pending], bereitsImSnapshot };
8379
+ }
8380
+
8294
8381
  // src/lib/hfEventLog.ts
8295
8382
  function treeUrl(namespace, subdir = "") {
8296
8383
  const parts = [namespace.replace(/\/$/, ""), subdir].filter(Boolean).join("/");
@@ -8410,6 +8497,16 @@ async function loadPendingEvents(namespace, token, sinceTs, knownPaths) {
8410
8497
  for (const f of pending) knownPaths?.add(f.path);
8411
8498
  return raw.flatMap((e) => Array.isArray(e) ? e : [e]);
8412
8499
  }
8500
+ async function findLatestSzenenSnapshotPath(namespace, token) {
8501
+ const files = await hfListDir(namespace, "", token);
8502
+ const treffer = files.filter((f) => f.type === "file" && istSzenenSnapshotDatei(f.path.split("/").pop() || "")).map((f) => f.path).sort((a, b) => b.localeCompare(a));
8503
+ return treffer[0] ?? null;
8504
+ }
8505
+ async function loadLatestSzenenSnapshot(namespace, token) {
8506
+ const pfad = await findLatestSzenenSnapshotPath(namespace, token);
8507
+ if (!pfad) return null;
8508
+ return parseSzenenSnapshot(await hfDownloadJsonByPath(pfad, token), pfad);
8509
+ }
8413
8510
  var SESSION_CLIENT_ID = `client-${crypto.randomUUID().slice(0, 8)}`;
8414
8511
  function tsToFilename(ts) {
8415
8512
  return new Date(ts).toISOString().replace(/:/g, "-").replace(".", "-");
@@ -8438,11 +8535,20 @@ async function writeHFEvent(namespace, token, type, payload, prevTs, options) {
8438
8535
 
8439
8536
  // src/lib/szenen/hfEventChannel.ts
8440
8537
  function createHfEventChannel(options) {
8441
- const { namespace, token, sinceTs = 0 } = options;
8538
+ const { namespace, token, sinceTs = 0, ohneSnapshot = false } = options;
8442
8539
  const knownPaths = /* @__PURE__ */ new Set();
8443
8540
  let cachedRawEvents = [];
8444
8541
  let syncInFlight = null;
8542
+ let snapshot = null;
8543
+ let snapshotGeladen = ohneSnapshot;
8445
8544
  const refresh = async () => {
8545
+ if (!snapshotGeladen) {
8546
+ snapshot = await loadLatestSzenenSnapshot(namespace, token);
8547
+ snapshotGeladen = true;
8548
+ for (const name of aufgenommeneDateien(snapshot)) {
8549
+ knownPaths.add(`${namespace}events/${name}`);
8550
+ }
8551
+ }
8446
8552
  const neue = await loadPendingEvents(namespace, token, sinceTs, knownPaths);
8447
8553
  if (neue.length) cachedRawEvents = [...cachedRawEvents, ...neue];
8448
8554
  };
@@ -8457,12 +8563,13 @@ function createHfEventChannel(options) {
8457
8563
  return {
8458
8564
  async readEvents() {
8459
8565
  await sync();
8460
- return cachedRawEvents.filter((event) => typeof event.type === "string" && event.type.startsWith(SZENEN_EVENT_PREFIX)).map((event) => ({
8566
+ const pending = cachedRawEvents.filter((event) => typeof event.type === "string" && event.type.startsWith(SZENEN_EVENT_PREFIX)).map((event) => ({
8461
8567
  type: event.type,
8462
8568
  payload: event.payload,
8463
8569
  clientId: event.clientId,
8464
8570
  ts: event.ts
8465
8571
  }));
8572
+ return mergeSnapshotAndPending(snapshot, pending).events;
8466
8573
  },
8467
8574
  async appendEvent(type, payload) {
8468
8575
  if (!type.startsWith(SZENEN_EVENT_PREFIX)) {
@@ -8478,6 +8585,7 @@ function createHfEventChannel(options) {
8478
8585
  // src/lib/szenen/inMemoryEventChannel.ts
8479
8586
  function createInMemoryEventChannel(options = {}) {
8480
8587
  const log = options.shared ?? [];
8588
+ const snapshot = options.snapshot ?? null;
8481
8589
  let tick = 0;
8482
8590
  const now = options.now ?? (() => ++tick);
8483
8591
  const clientId = options.clientId ?? "client-a";
@@ -8486,7 +8594,8 @@ function createInMemoryEventChannel(options = {}) {
8486
8594
  return log;
8487
8595
  },
8488
8596
  async readEvents() {
8489
- return log.map((event) => ({ ...event }));
8597
+ const { events } = mergeSnapshotAndPending(snapshot, log);
8598
+ return events.map((event) => ({ ...event }));
8490
8599
  },
8491
8600
  async appendEvent(type, payload) {
8492
8601
  log.push({ type, payload, clientId, ts: now() });
@@ -8495,7 +8604,7 @@ function createInMemoryEventChannel(options = {}) {
8495
8604
  log.push(event);
8496
8605
  },
8497
8606
  withClient(otherClientId) {
8498
- return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log });
8607
+ return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log, snapshot });
8499
8608
  }
8500
8609
  };
8501
8610
  return channel;
@@ -19403,6 +19512,9 @@ var SzenenView = ({
19403
19512
  SZENEN_EVENT_TYPES,
19404
19513
  SZENEN_ITEM_PREFIX,
19405
19514
  SZENEN_SCHEMAS,
19515
+ SZENEN_SNAPSHOT_FILE,
19516
+ SZENEN_SNAPSHOT_PREFIX,
19517
+ SZENEN_SNAPSHOT_SCHEMA_VERSION,
19406
19518
  SzenenView,
19407
19519
  UNCHECKED_PUBLISH_RULES,
19408
19520
  UPLOAD_MAX_BYTES,
@@ -19415,6 +19527,7 @@ var SzenenView = ({
19415
19527
  buildDerivationSystemInstruction,
19416
19528
  buildDerivationUserPrompt,
19417
19529
  buildSystemInstruction,
19530
+ buildSzenenSnapshot,
19418
19531
  buildUserPrompt,
19419
19532
  buildVersionDag,
19420
19533
  callOptional,
@@ -19505,6 +19618,7 @@ var SzenenView = ({
19505
19618
  isOk,
19506
19619
  isProjectionCurrent,
19507
19620
  isSzenenItemId,
19621
+ istSzenenSnapshotDatei,
19508
19622
  istZipDatei,
19509
19623
  itemIdForRun,
19510
19624
  ladeVorschauen,
@@ -19512,6 +19626,7 @@ var SzenenView = ({
19512
19626
  linkFor,
19513
19627
  locatorTeile,
19514
19628
  logRevisionOf,
19629
+ mergeSnapshotAndPending,
19515
19630
  mergeSzenenBatchOrigin,
19516
19631
  mitDefaultVorlage,
19517
19632
  noticeFor,
@@ -19520,6 +19635,7 @@ var SzenenView = ({
19520
19635
  parseDerivationResponse,
19521
19636
  parseRunResponse,
19522
19637
  parseSeedListe,
19638
+ parseSzenenSnapshot,
19523
19639
  preferredHeadRevisionOf,
19524
19640
  preferredVersionId,
19525
19641
  promptDiagnosticsOf,
@@ -19547,6 +19663,7 @@ var SzenenView = ({
19547
19663
  selectableTargetModels,
19548
19664
  showChain,
19549
19665
  simulatedAnswerFor,
19666
+ szenenSnapshotFilename,
19550
19667
  totalModelCalls,
19551
19668
  typAusBytes,
19552
19669
  unclassifiedPublishRules,
package/dist/szenen.mjs CHANGED
@@ -21,6 +21,9 @@ import {
21
21
  SZENEN_EVENT_TYPES,
22
22
  SZENEN_ITEM_PREFIX,
23
23
  SZENEN_SCHEMAS,
24
+ SZENEN_SNAPSHOT_FILE,
25
+ SZENEN_SNAPSHOT_PREFIX,
26
+ SZENEN_SNAPSHOT_SCHEMA_VERSION,
24
27
  SzenenView,
25
28
  UNCHECKED_PUBLISH_RULES,
26
29
  UPLOAD_MAX_BYTES,
@@ -32,6 +35,7 @@ import {
32
35
  bildPfad,
33
36
  buildSystemInstruction,
34
37
  buildSystemInstruction2,
38
+ buildSzenenSnapshot,
35
39
  buildUserPrompt,
36
40
  buildUserPrompt2,
37
41
  callOptional,
@@ -112,6 +116,7 @@ import {
112
116
  isOk,
113
117
  isProjectionCurrent,
114
118
  isSzenenItemId,
119
+ istSzenenSnapshotDatei,
115
120
  istZipDatei,
116
121
  itemIdForRun,
117
122
  ladeVorschauen,
@@ -119,6 +124,7 @@ import {
119
124
  linkFor,
120
125
  locatorTeile,
121
126
  logRevisionOf,
127
+ mergeSnapshotAndPending,
122
128
  mergeSzenenBatchOrigin,
123
129
  mitDefaultVorlage,
124
130
  noticeFor,
@@ -127,6 +133,7 @@ import {
127
133
  parseDerivationResponse,
128
134
  parseRunResponse,
129
135
  parseSeedListe,
136
+ parseSzenenSnapshot,
130
137
  preferredHeadRevisionOf,
131
138
  promptDiagnosticsOf,
132
139
  publishedHeadsOf,
@@ -150,6 +157,7 @@ import {
150
157
  selectableTargetModels,
151
158
  showChain,
152
159
  simulatedAnswerFor,
160
+ szenenSnapshotFilename,
153
161
  typAusBytes,
154
162
  unclassifiedPublishRules,
155
163
  unsupportedReason,
@@ -158,7 +166,7 @@ import {
158
166
  validateElementVersion,
159
167
  validatePayload,
160
168
  withReference
161
- } from "./chunk-GHKN2VX3.mjs";
169
+ } from "./chunk-5QA6DTJ6.mjs";
162
170
  import {
163
171
  ContractViolation,
164
172
  STYLE_PAYLOAD,
@@ -172,7 +180,6 @@ import {
172
180
  preferredVersionId,
173
181
  resolvePreferredHead
174
182
  } from "./chunk-FUY2OCVC.mjs";
175
- import "./chunk-NBUS7AWR.mjs";
176
183
 
177
184
  // src/lib/szenen/providerCheckStore.ts
178
185
  function collectProviderChecks(events) {
@@ -195,6 +202,7 @@ function totalModelCalls(checks) {
195
202
  // src/lib/szenen/inMemoryEventChannel.ts
196
203
  function createInMemoryEventChannel(options = {}) {
197
204
  const log = options.shared ?? [];
205
+ const snapshot = options.snapshot ?? null;
198
206
  let tick = 0;
199
207
  const now = options.now ?? (() => ++tick);
200
208
  const clientId = options.clientId ?? "client-a";
@@ -203,7 +211,8 @@ function createInMemoryEventChannel(options = {}) {
203
211
  return log;
204
212
  },
205
213
  async readEvents() {
206
- return log.map((event) => ({ ...event }));
214
+ const { events } = mergeSnapshotAndPending(snapshot, log);
215
+ return events.map((event) => ({ ...event }));
207
216
  },
208
217
  async appendEvent(type, payload) {
209
218
  log.push({ type, payload, clientId, ts: now() });
@@ -212,7 +221,7 @@ function createInMemoryEventChannel(options = {}) {
212
221
  log.push(event);
213
222
  },
214
223
  withClient(otherClientId) {
215
- return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log });
224
+ return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log, snapshot });
216
225
  }
217
226
  };
218
227
  return channel;
@@ -1666,6 +1675,9 @@ export {
1666
1675
  SZENEN_EVENT_TYPES,
1667
1676
  SZENEN_ITEM_PREFIX,
1668
1677
  SZENEN_SCHEMAS,
1678
+ SZENEN_SNAPSHOT_FILE,
1679
+ SZENEN_SNAPSHOT_PREFIX,
1680
+ SZENEN_SNAPSHOT_SCHEMA_VERSION,
1669
1681
  SzenenView,
1670
1682
  UNCHECKED_PUBLISH_RULES,
1671
1683
  UPLOAD_MAX_BYTES,
@@ -1678,6 +1690,7 @@ export {
1678
1690
  buildSystemInstruction as buildDerivationSystemInstruction,
1679
1691
  buildUserPrompt as buildDerivationUserPrompt,
1680
1692
  buildSystemInstruction2 as buildSystemInstruction,
1693
+ buildSzenenSnapshot,
1681
1694
  buildUserPrompt2 as buildUserPrompt,
1682
1695
  buildVersionDag,
1683
1696
  callOptional,
@@ -1768,6 +1781,7 @@ export {
1768
1781
  isOk,
1769
1782
  isProjectionCurrent,
1770
1783
  isSzenenItemId,
1784
+ istSzenenSnapshotDatei,
1771
1785
  istZipDatei,
1772
1786
  itemIdForRun,
1773
1787
  ladeVorschauen,
@@ -1775,6 +1789,7 @@ export {
1775
1789
  linkFor,
1776
1790
  locatorTeile,
1777
1791
  logRevisionOf,
1792
+ mergeSnapshotAndPending,
1778
1793
  mergeSzenenBatchOrigin,
1779
1794
  mitDefaultVorlage,
1780
1795
  noticeFor,
@@ -1783,6 +1798,7 @@ export {
1783
1798
  parseDerivationResponse,
1784
1799
  parseRunResponse,
1785
1800
  parseSeedListe,
1801
+ parseSzenenSnapshot,
1786
1802
  preferredHeadRevisionOf,
1787
1803
  preferredVersionId,
1788
1804
  promptDiagnosticsOf,
@@ -1810,6 +1826,7 @@ export {
1810
1826
  selectableTargetModels,
1811
1827
  showChain,
1812
1828
  simulatedAnswerFor,
1829
+ szenenSnapshotFilename,
1813
1830
  totalModelCalls,
1814
1831
  typAusBytes,
1815
1832
  unclassifiedPublishRules,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "6.1.0",
3
+ "version": "7.2.0",
4
4
  "description": "Shared tools and hooks for Fine Art flow apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",