@rslsp1/fa-app-tools 7.0.1 → 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-B2YV4TNI.mjs";
169
+ } from "./chunk-5QA6DTJ6.mjs";
162
170
  import {
163
171
  ContractViolation,
164
172
  STYLE_PAYLOAD,
@@ -194,6 +202,7 @@ function totalModelCalls(checks) {
194
202
  // src/lib/szenen/inMemoryEventChannel.ts
195
203
  function createInMemoryEventChannel(options = {}) {
196
204
  const log = options.shared ?? [];
205
+ const snapshot = options.snapshot ?? null;
197
206
  let tick = 0;
198
207
  const now = options.now ?? (() => ++tick);
199
208
  const clientId = options.clientId ?? "client-a";
@@ -202,7 +211,8 @@ function createInMemoryEventChannel(options = {}) {
202
211
  return log;
203
212
  },
204
213
  async readEvents() {
205
- return log.map((event) => ({ ...event }));
214
+ const { events } = mergeSnapshotAndPending(snapshot, log);
215
+ return events.map((event) => ({ ...event }));
206
216
  },
207
217
  async appendEvent(type, payload) {
208
218
  log.push({ type, payload, clientId, ts: now() });
@@ -211,7 +221,7 @@ function createInMemoryEventChannel(options = {}) {
211
221
  log.push(event);
212
222
  },
213
223
  withClient(otherClientId) {
214
- return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log });
224
+ return createInMemoryEventChannel({ clientId: otherClientId, now, shared: log, snapshot });
215
225
  }
216
226
  };
217
227
  return channel;
@@ -1665,6 +1675,9 @@ export {
1665
1675
  SZENEN_EVENT_TYPES,
1666
1676
  SZENEN_ITEM_PREFIX,
1667
1677
  SZENEN_SCHEMAS,
1678
+ SZENEN_SNAPSHOT_FILE,
1679
+ SZENEN_SNAPSHOT_PREFIX,
1680
+ SZENEN_SNAPSHOT_SCHEMA_VERSION,
1668
1681
  SzenenView,
1669
1682
  UNCHECKED_PUBLISH_RULES,
1670
1683
  UPLOAD_MAX_BYTES,
@@ -1677,6 +1690,7 @@ export {
1677
1690
  buildSystemInstruction as buildDerivationSystemInstruction,
1678
1691
  buildUserPrompt as buildDerivationUserPrompt,
1679
1692
  buildSystemInstruction2 as buildSystemInstruction,
1693
+ buildSzenenSnapshot,
1680
1694
  buildUserPrompt2 as buildUserPrompt,
1681
1695
  buildVersionDag,
1682
1696
  callOptional,
@@ -1767,6 +1781,7 @@ export {
1767
1781
  isOk,
1768
1782
  isProjectionCurrent,
1769
1783
  isSzenenItemId,
1784
+ istSzenenSnapshotDatei,
1770
1785
  istZipDatei,
1771
1786
  itemIdForRun,
1772
1787
  ladeVorschauen,
@@ -1774,6 +1789,7 @@ export {
1774
1789
  linkFor,
1775
1790
  locatorTeile,
1776
1791
  logRevisionOf,
1792
+ mergeSnapshotAndPending,
1777
1793
  mergeSzenenBatchOrigin,
1778
1794
  mitDefaultVorlage,
1779
1795
  noticeFor,
@@ -1782,6 +1798,7 @@ export {
1782
1798
  parseDerivationResponse,
1783
1799
  parseRunResponse,
1784
1800
  parseSeedListe,
1801
+ parseSzenenSnapshot,
1785
1802
  preferredHeadRevisionOf,
1786
1803
  preferredVersionId,
1787
1804
  promptDiagnosticsOf,
@@ -1809,6 +1826,7 @@ export {
1809
1826
  selectableTargetModels,
1810
1827
  showChain,
1811
1828
  simulatedAnswerFor,
1829
+ szenenSnapshotFilename,
1812
1830
  totalModelCalls,
1813
1831
  typAusBytes,
1814
1832
  unclassifiedPublishRules,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "7.0.1",
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",