@prometheus-ags/entity-graph-core 4.0.1 → 4.1.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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as SortSpec, F as FilterSpec, E as EntityType, G as GraphStore$1, a as EntityId, b as SyncOrigin, Q as QueryKey, u as useGraphStore, c as EntitySnapshot, d as EntitySyncMetadata, g as graphStore } from './graph-ClW3HD8B.js';
2
- export { C as CompletenessMode, e as EMPTY_ENTITY_STATE, f as EMPTY_IDS, h as EMPTY_LIST_STATE, i as EMPTY_SYNC_METADATA, j as EntityError, k as EntityErrorOptions, l as EntityState, m as FetchedEntityBatch, n as FetchedListProjection, o as FetchedListTarget, p as FilterClause, q as FilterGroup, r as FilterOperator, s as GraphState, I as IngestFetchedListOptions, L as ListResultMeta, t as ListState, v as SortClause, w as SortDirection, T as TerminalError, x as TransientError, V as ViewDescriptor, y as createGraphStore, z as flattenClauses, A as hasCustomPredicates, B as toEntityError, D as toGraphQLVariables, H as toRestParams, J as toSQLClauses } from './graph-ClW3HD8B.js';
1
+ import { S as SortSpec, F as FilterSpec, E as EntityType, G as GraphStore$1, a as EntityId, b as SyncOrigin, Q as QueryKey, u as useGraphStore, c as EntitySnapshot, d as EntitySyncMetadata, g as graphStore } from './graph-QfI6o5eV.js';
2
+ export { C as CompletenessMode, e as EMPTY_ENTITY_STATE, f as EMPTY_IDS, h as EMPTY_LIST_STATE, i as EMPTY_SYNC_METADATA, j as EntityError, k as EntityErrorOptions, l as EntityState, m as FetchedEntityBatch, n as FetchedListProjection, o as FetchedListTarget, p as FilterClause, q as FilterGroup, r as FilterOperator, s as GraphState, I as IngestFetchedListOptions, L as ListResultMeta, t as ListState, v as SortClause, w as SortDirection, T as TerminalError, x as TransientError, V as ViewDescriptor, y as createGraphStore, z as flattenClauses, A as hasCustomPredicates, B as toEntityError, D as toGraphQLVariables, H as toRestParams, J as toSQLClauses } from './graph-QfI6o5eV.js';
3
3
  import * as zustand_vanilla from 'zustand/vanilla';
4
4
 
5
5
  /**
@@ -663,17 +663,14 @@ declare function exportGraphSnapshot(opts: GraphSnapshotExportOptions): string;
663
663
  declare function createGraphTool<TInput, TResult>(handler: (input: TInput, ctx: GraphToolContext) => Promise<TResult> | TResult): (input: TInput) => TResult | Promise<TResult>;
664
664
  declare function createSchemaGraphTool<TInput, TResult>(handler: (input: TInput, ctx: SchemaGraphToolContext) => Promise<TResult> | TResult): (input: TInput) => TResult | Promise<TResult>;
665
665
 
666
- interface GraphPersistenceAdapter {
667
- get: (key: string) => Promise<string | null> | string | null;
668
- set: (key: string, value: string) => Promise<void> | void;
669
- remove?: (key: string) => Promise<void> | void;
670
- }
671
- interface GraphActionRecord {
672
- id: string;
673
- key: string;
674
- input: unknown;
675
- enqueuedAt: string;
676
- }
666
+ /**
667
+ * Types shared by the local-first runtime and its runtime scope.
668
+ *
669
+ * These live here, not in local-first-runtime.ts, because runtime-scope.ts
670
+ * needs them too. Importing them from the runtime would make the two modules
671
+ * import each other, and TypeScript resolves that cycle by widening the types
672
+ * to `unknown` — which type-checks at the definition and fails at every use.
673
+ */
677
674
  interface GraphSyncStatus {
678
675
  phase: "idle" | "hydrating" | "syncing" | "ready" | "offline" | "error";
679
676
  isOnline: boolean;
@@ -684,6 +681,65 @@ interface GraphSyncStatus {
684
681
  storageKey: string | null;
685
682
  error: string | null;
686
683
  }
684
+ interface GraphActionRecord {
685
+ id: string;
686
+ key: string;
687
+ input: unknown;
688
+ enqueuedAt: string;
689
+ }
690
+ interface ReplayRetryPolicy {
691
+ maxAttempts?: number;
692
+ initialDelayMs?: number;
693
+ maxDelayMs?: number;
694
+ backoffFactor?: number;
695
+ jitter?: "full" | "equal" | "none";
696
+ poisonHandler?: (action: GraphActionRecord, error: unknown) => void | Promise<void>;
697
+ }
698
+
699
+ /** Create an independent sync-status store. Each runtime owns one. */
700
+ declare function createGraphSyncStatusStore(): zustand_vanilla.StoreApi<{
701
+ status: GraphSyncStatus;
702
+ setStatus: (status: Partial<GraphSyncStatus>) => void;
703
+ }>;
704
+ type GraphSyncStatusStore = ReturnType<typeof createGraphSyncStatusStore>;
705
+ /**
706
+ * Per-runtime state container.
707
+ *
708
+ * Both fields were previously module-level singletons shared by every runtime
709
+ * in the process. That was not merely shared state — `hydrateGraphFromStorage`
710
+ * clears the pending set before repopulating it, so a second runtime hydrating
711
+ * erased the first runtime's un-settled actions. On an account or practice
712
+ * switch that is silent write loss, which is why this is scoped per runtime
713
+ * (ADR-009 G1).
714
+ */
715
+ interface RuntimeScope {
716
+ pendingActions: Map<string, GraphActionRecord>;
717
+ statusStore: GraphSyncStatusStore;
718
+ }
719
+ /** Create an isolated runtime scope. */
720
+ declare function createRuntimeScope(): RuntimeScope;
721
+
722
+ /**
723
+ * Replay retry policy: defaults, exponential backoff, and jitter.
724
+ *
725
+ * Separated from the runtime because it is pure scheduling arithmetic — it
726
+ * touches no store, no adapter, and no persisted state, and is the part most
727
+ * likely to be reasoned about (or tuned) on its own.
728
+ */
729
+ interface ResolvedRetryPolicy {
730
+ maxAttempts: number;
731
+ initialDelayMs: number;
732
+ maxDelayMs: number;
733
+ backoffFactor: number;
734
+ jitter: "full" | "equal" | "none";
735
+ poisonHandler?: (action: GraphActionRecord, error: unknown) => void | Promise<void>;
736
+ }
737
+
738
+ interface GraphPersistenceAdapter {
739
+ get: (key: string) => Promise<string | null> | string | null;
740
+ set: (key: string, value: string) => Promise<void> | void;
741
+ remove?: (key: string) => Promise<void> | void;
742
+ }
687
743
  interface GraphSnapshotPayload {
688
744
  version: 1;
689
745
  snapshot: {
@@ -731,14 +787,6 @@ interface HydrateGraphFromStorageOptions {
731
787
  * Defaults: 5 attempts, starting at 500ms, doubling up to 30s, with
732
788
  * "equal" jitter (random in `[delay/2, delay]`).
733
789
  */
734
- interface ReplayRetryPolicy {
735
- maxAttempts?: number;
736
- initialDelayMs?: number;
737
- maxDelayMs?: number;
738
- backoffFactor?: number;
739
- jitter?: "full" | "equal" | "none";
740
- poisonHandler?: (action: GraphActionRecord, error: unknown) => void | Promise<void>;
741
- }
742
790
  interface StartLocalFirstGraphOptions {
743
791
  storage: GraphPersistenceAdapter;
744
792
  store?: GraphStore$1;
@@ -777,32 +825,11 @@ interface LocalFirstGraphRuntime {
777
825
  */
778
826
  scope: RuntimeScope;
779
827
  }
828
+
780
829
  declare const graphSyncStatusStore: zustand_vanilla.StoreApi<{
781
830
  status: GraphSyncStatus;
782
831
  setStatus: (status: Partial<GraphSyncStatus>) => void;
783
832
  }>;
784
- /**
785
- * Per-runtime state: the pending-action set and the status store that runtime
786
- * publishes to.
787
- *
788
- * Both were previously module-level singletons shared by every runtime in the
789
- * process. That was not merely shared state — `hydrateGraphFromStorage` clears
790
- * the pending set before repopulating it, so a second runtime hydrating erased
791
- * the first runtime's un-settled actions. On an account or practice switch that
792
- * is silent write loss, which is why this is scoped per runtime (ADR-009 G1).
793
- */
794
- interface RuntimeScope {
795
- pendingActions: Map<string, GraphActionRecord>;
796
- statusStore: GraphSyncStatusStore;
797
- }
798
- type GraphSyncStatusStore = ReturnType<typeof createGraphSyncStatusStore>;
799
- /** Create an independent sync-status store. Each runtime owns one. */
800
- declare function createGraphSyncStatusStore(): zustand_vanilla.StoreApi<{
801
- status: GraphSyncStatus;
802
- setStatus: (status: Partial<GraphSyncStatus>) => void;
803
- }>;
804
- /** Create an isolated runtime scope. */
805
- declare function createRuntimeScope(): RuntimeScope;
806
833
  declare function getGraphSyncStatus(): GraphSyncStatus;
807
834
  declare function persistGraphToStorage(opts: PersistGraphToStorageOptions): Promise<{
808
835
  ok: true;
@@ -828,14 +855,6 @@ declare function hydrateGraphFromStorage(opts: HydrateGraphFromStorageOptions):
828
855
  error?: undefined;
829
856
  }>;
830
857
  declare function startLocalFirstGraph(opts: StartLocalFirstGraphOptions): LocalFirstGraphRuntime;
831
- interface ResolvedRetryPolicy {
832
- maxAttempts: number;
833
- initialDelayMs: number;
834
- maxDelayMs: number;
835
- backoffFactor: number;
836
- jitter: "full" | "equal" | "none";
837
- poisonHandler?: (action: GraphActionRecord, error: unknown) => void | Promise<void>;
838
- }
839
858
  /**
840
859
  * Attempt to replay an action up to `maxAttempts` times. On exhaustion the
841
860
  * action goes to "poison" — the optional handler is invoked and the function
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { graphStore, useGraphStore, subscribeDevtoolsEvent, getGraphDevtoolsCompatibilityDelegate, subscribeGraphDevtoolsCompatibility, matchesFilter, matchesSearch, compareEntities, emitLegacyDevtoolsEvent, __require } from './chunk-H7NBREZV.mjs';
2
- export { EMPTY_ENTITY_STATE, EMPTY_IDS, EMPTY_LIST_STATE, EMPTY_SYNC_METADATA, applyView, attachGlobalListeners, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createGraphStore, dedupe, fetchEntity, fetchList, findInsertionIndex, getActiveSubscriberCount, getEngineOptions, getMergeStrategy, getSchema, graphStore, hasMergeStrategy, lwwStrategy, matchesFilter, matchesSearch, readRelations, registerMergeStrategy, registerSchema, registerSubscriber, serializeKey, setDefaultMergeStrategy, startGarbageCollector, stopGarbageCollector, subscribeDevtoolsEvent, subscribeSubscriberStats, unregisterSubscriber, useGraphStore } from './chunk-H7NBREZV.mjs';
1
+ import { graphStore, useGraphStore, subscribeDevtoolsEvent, getGraphDevtoolsCompatibilityDelegate, subscribeGraphDevtoolsCompatibility, matchesFilter, matchesSearch, compareEntities, emitLegacyDevtoolsEvent, __require } from './chunk-64YZRB56.mjs';
2
+ export { EMPTY_ENTITY_STATE, EMPTY_IDS, EMPTY_LIST_STATE, EMPTY_SYNC_METADATA, applyView, attachGlobalListeners, cascadeInvalidation, checkCompleteness, compareEntities, configureEngine, createGraphStore, dedupe, fetchEntity, fetchList, findInsertionIndex, getActiveSubscriberCount, getEngineOptions, getMergeStrategy, getSchema, graphStore, hasMergeStrategy, lwwStrategy, matchesFilter, matchesSearch, readRelations, registerMergeStrategy, registerSchema, registerSubscriber, serializeKey, setDefaultMergeStrategy, startGarbageCollector, stopGarbageCollector, subscribeDevtoolsEvent, subscribeSubscriberStats, unregisterSubscriber, useGraphStore } from './chunk-64YZRB56.mjs';
3
3
  import { createStore } from 'zustand/vanilla';
4
4
 
5
5
  // src/errors.ts
@@ -949,6 +949,57 @@ function createSchemaGraphTool(handler) {
949
949
  exportGraphSnapshotWithSchemas
950
950
  });
951
951
  }
952
+ var initialStatus = {
953
+ phase: "idle",
954
+ isOnline: true,
955
+ isSynced: true,
956
+ pendingActions: 0,
957
+ lastHydratedAt: null,
958
+ lastPersistedAt: null,
959
+ storageKey: null,
960
+ error: null
961
+ };
962
+ function createGraphSyncStatusStore() {
963
+ return createStore()((set) => ({
964
+ status: { ...initialStatus },
965
+ setStatus: (status) => set((state) => ({ status: { ...state.status, ...status } }))
966
+ }));
967
+ }
968
+ function createRuntimeScope() {
969
+ return {
970
+ pendingActions: /* @__PURE__ */ new Map(),
971
+ statusStore: createGraphSyncStatusStore()
972
+ };
973
+ }
974
+
975
+ // src/replay-retry.ts
976
+ function resolveRetryPolicy(policy) {
977
+ return {
978
+ maxAttempts: policy?.maxAttempts ?? 5,
979
+ initialDelayMs: policy?.initialDelayMs ?? 500,
980
+ maxDelayMs: policy?.maxDelayMs ?? 3e4,
981
+ backoffFactor: policy?.backoffFactor ?? 2,
982
+ jitter: policy?.jitter ?? "equal",
983
+ poisonHandler: policy?.poisonHandler
984
+ };
985
+ }
986
+ function computeDelay(policy, attempt) {
987
+ const base = Math.min(
988
+ policy.initialDelayMs * Math.pow(policy.backoffFactor, Math.max(0, attempt - 1)),
989
+ policy.maxDelayMs
990
+ );
991
+ switch (policy.jitter) {
992
+ case "none":
993
+ return base;
994
+ case "full":
995
+ return Math.random() * base;
996
+ case "equal":
997
+ default:
998
+ return base / 2 + Math.random() * (base / 2);
999
+ }
1000
+ }
1001
+
1002
+ // src/local-first-runtime.ts
952
1003
  var DEFAULT_STORAGE_KEY = "prometheus:graph";
953
1004
  var graphSyncStatusStore = createStore()((set) => ({
954
1005
  status: {
@@ -968,27 +1019,6 @@ var graphSyncStatusStore = createStore()((set) => ({
968
1019
  }
969
1020
  }))
970
1021
  }));
971
- function createGraphSyncStatusStore() {
972
- return createStore()((set) => ({
973
- status: {
974
- phase: "idle",
975
- isOnline: true,
976
- isSynced: true,
977
- pendingActions: 0,
978
- lastHydratedAt: null,
979
- lastPersistedAt: null,
980
- storageKey: null,
981
- error: null
982
- },
983
- setStatus: (status) => set((state) => ({ status: { ...state.status, ...status } }))
984
- }));
985
- }
986
- function createRuntimeScope() {
987
- return {
988
- pendingActions: /* @__PURE__ */ new Map(),
989
- statusStore: createGraphSyncStatusStore()
990
- };
991
- }
992
1022
  var fallbackScope = {
993
1023
  pendingActions: /* @__PURE__ */ new Map(),
994
1024
  statusStore: graphSyncStatusStore
@@ -1198,31 +1228,6 @@ function cloneGraphSnapshot(storeApi) {
1198
1228
  lists: structuredClone(state.lists)
1199
1229
  };
1200
1230
  }
1201
- function resolveRetryPolicy(policy) {
1202
- return {
1203
- maxAttempts: policy?.maxAttempts ?? 5,
1204
- initialDelayMs: policy?.initialDelayMs ?? 500,
1205
- maxDelayMs: policy?.maxDelayMs ?? 3e4,
1206
- backoffFactor: policy?.backoffFactor ?? 2,
1207
- jitter: policy?.jitter ?? "equal",
1208
- poisonHandler: policy?.poisonHandler
1209
- };
1210
- }
1211
- function computeDelay(policy, attempt) {
1212
- const base = Math.min(
1213
- policy.initialDelayMs * Math.pow(policy.backoffFactor, Math.max(0, attempt - 1)),
1214
- policy.maxDelayMs
1215
- );
1216
- switch (policy.jitter) {
1217
- case "none":
1218
- return base;
1219
- case "full":
1220
- return Math.random() * base;
1221
- case "equal":
1222
- default:
1223
- return base / 2 + Math.random() * (base / 2);
1224
- }
1225
- }
1226
1231
  function sleep(ms) {
1227
1232
  if (ms <= 0) return Promise.resolve();
1228
1233
  return new Promise((r) => setTimeout(r, ms));