@nicia-ai/typegraph 0.58.0 → 0.59.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/CHANGELOG.md +22 -0
- package/README.md +12 -0
- package/dist/{atomic-mutation-program-CPcn0ZPu.d.ts → atomic-mutation-program-BNvJ13bq.d.ts} +1 -1
- package/dist/{atomic-mutation-program-AqOe51XD.d.cts → atomic-mutation-program-DOVE147J.d.cts} +1 -1
- package/dist/backend/drizzle/engine/index.cjs +8 -8
- package/dist/backend/drizzle/engine/index.d.cts +9 -9
- package/dist/backend/drizzle/engine/index.d.ts +9 -9
- package/dist/backend/drizzle/engine/index.js +3 -3
- package/dist/backend/drizzle/indexes.cjs +6 -6
- package/dist/backend/drizzle/indexes.d.cts +1 -1
- package/dist/backend/drizzle/indexes.d.ts +1 -1
- package/dist/backend/drizzle/indexes.js +2 -2
- package/dist/backend/index.d.cts +7 -7
- package/dist/backend/index.d.ts +7 -7
- package/dist/backend/postgres/index.cjs +17 -17
- package/dist/backend/postgres/index.d.cts +8 -8
- package/dist/backend/postgres/index.d.ts +8 -8
- package/dist/backend/postgres/index.js +3 -3
- package/dist/backend/postgres/pglite-store.cjs +1 -1
- package/dist/backend/postgres/pglite-store.d.cts +6 -6
- package/dist/backend/postgres/pglite-store.d.ts +6 -6
- package/dist/backend/postgres/pglite-store.js +1 -1
- package/dist/backend/postgres/pglite.cjs +5 -5
- package/dist/backend/postgres/pglite.d.cts +3 -3
- package/dist/backend/postgres/pglite.d.ts +3 -3
- package/dist/backend/postgres/pglite.js +4 -4
- package/dist/backend/sqlite/index.cjs +16 -16
- package/dist/backend/sqlite/index.d.cts +7 -7
- package/dist/backend/sqlite/index.d.ts +7 -7
- package/dist/backend/sqlite/index.js +3 -3
- package/dist/backend/sqlite/libsql.cjs +7 -7
- package/dist/backend/sqlite/libsql.d.cts +3 -3
- package/dist/backend/sqlite/libsql.d.ts +3 -3
- package/dist/backend/sqlite/libsql.js +3 -3
- package/dist/backend/sqlite/local-store.cjs +1 -1
- package/dist/backend/sqlite/local-store.d.cts +6 -6
- package/dist/backend/sqlite/local-store.d.ts +6 -6
- package/dist/backend/sqlite/local-store.js +1 -1
- package/dist/backend/sqlite/local.cjs +5 -5
- package/dist/backend/sqlite/local.d.cts +3 -3
- package/dist/backend/sqlite/local.d.ts +3 -3
- package/dist/backend/sqlite/local.js +4 -4
- package/dist/{chunk-QR6V2BXA.cjs → chunk-26CL47SW.cjs} +13 -13
- package/dist/{chunk-QR6V2BXA.cjs.map → chunk-26CL47SW.cjs.map} +1 -1
- package/dist/{chunk-U53HFE4L.cjs → chunk-2GZL5ED3.cjs} +16 -16
- package/dist/{chunk-U53HFE4L.cjs.map → chunk-2GZL5ED3.cjs.map} +1 -1
- package/dist/{chunk-QIKO6DL5.js → chunk-2QNFFAMF.js} +3 -3
- package/dist/{chunk-QIKO6DL5.js.map → chunk-2QNFFAMF.js.map} +1 -1
- package/dist/{chunk-M7TRJXFE.js → chunk-3GX5HTPP.js} +3 -3
- package/dist/{chunk-M7TRJXFE.js.map → chunk-3GX5HTPP.js.map} +1 -1
- package/dist/{chunk-US3BLFWM.js → chunk-7GNPCBS2.js} +3 -3
- package/dist/{chunk-US3BLFWM.js.map → chunk-7GNPCBS2.js.map} +1 -1
- package/dist/{chunk-FHFPUORN.cjs → chunk-CA76FVJB.cjs} +1234 -306
- package/dist/chunk-CA76FVJB.cjs.map +1 -0
- package/dist/{chunk-4MZQVVPX.cjs → chunk-D5CHUSW7.cjs} +33 -2
- package/dist/chunk-D5CHUSW7.cjs.map +1 -0
- package/dist/{chunk-TKEJR2UL.cjs → chunk-DWO6WZP5.cjs} +6 -6
- package/dist/{chunk-TKEJR2UL.cjs.map → chunk-DWO6WZP5.cjs.map} +1 -1
- package/dist/{chunk-5C4OYYDD.js → chunk-DZ3ETMXF.js} +4 -4
- package/dist/{chunk-5C4OYYDD.js.map → chunk-DZ3ETMXF.js.map} +1 -1
- package/dist/{chunk-IV3FENV2.js → chunk-E6PU35DE.js} +4 -4
- package/dist/{chunk-IV3FENV2.js.map → chunk-E6PU35DE.js.map} +1 -1
- package/dist/{chunk-GUMNJJFP.cjs → chunk-EN67I47R.cjs} +9 -9
- package/dist/{chunk-GUMNJJFP.cjs.map → chunk-EN67I47R.cjs.map} +1 -1
- package/dist/{chunk-BYBMDK6X.js → chunk-GYOQAV6R.js} +3 -3
- package/dist/{chunk-BYBMDK6X.js.map → chunk-GYOQAV6R.js.map} +1 -1
- package/dist/{chunk-GTW5YKFV.js → chunk-HCNC53MU.js} +3 -3
- package/dist/{chunk-GTW5YKFV.js.map → chunk-HCNC53MU.js.map} +1 -1
- package/dist/{chunk-BMATB57B.cjs → chunk-KW3ON5IU.cjs} +11 -11
- package/dist/{chunk-BMATB57B.cjs.map → chunk-KW3ON5IU.cjs.map} +1 -1
- package/dist/{chunk-GK62U3S5.js → chunk-LOFUF6L7.js} +3 -3
- package/dist/{chunk-GK62U3S5.js.map → chunk-LOFUF6L7.js.map} +1 -1
- package/dist/{chunk-7JUD57B4.js → chunk-MKQY4ZLZ.js} +996 -68
- package/dist/chunk-MKQY4ZLZ.js.map +1 -0
- package/dist/{chunk-YTYB5KCQ.js → chunk-OH7QRGPQ.js} +33 -2
- package/dist/chunk-OH7QRGPQ.js.map +1 -0
- package/dist/{chunk-WAG3NVD7.cjs → chunk-QBQ465OX.cjs} +12 -12
- package/dist/{chunk-WAG3NVD7.cjs.map → chunk-QBQ465OX.cjs.map} +1 -1
- package/dist/{chunk-CRROO6PK.cjs → chunk-QHP2BCBJ.cjs} +4 -4
- package/dist/{chunk-CRROO6PK.cjs.map → chunk-QHP2BCBJ.cjs.map} +1 -1
- package/dist/{chunk-ZHLWPHNT.cjs → chunk-RJ3GVX73.cjs} +6 -6
- package/dist/{chunk-ZHLWPHNT.cjs.map → chunk-RJ3GVX73.cjs.map} +1 -1
- package/dist/{chunk-SYKR6MVR.cjs → chunk-T2M2S5YZ.cjs} +59 -59
- package/dist/{chunk-SYKR6MVR.cjs.map → chunk-T2M2S5YZ.cjs.map} +1 -1
- package/dist/{chunk-OESX3T5K.js → chunk-TNNDNSNH.js} +4 -4
- package/dist/{chunk-OESX3T5K.js.map → chunk-TNNDNSNH.js.map} +1 -1
- package/dist/{chunk-C3CN2C2T.cjs → chunk-UOHFBYYH.cjs} +4 -4
- package/dist/{chunk-C3CN2C2T.cjs.map → chunk-UOHFBYYH.cjs.map} +1 -1
- package/dist/{chunk-DV24YZHG.js → chunk-V3JKR2CN.js} +4 -4
- package/dist/{chunk-DV24YZHG.js.map → chunk-V3JKR2CN.js.map} +1 -1
- package/dist/{chunk-CVO2ZPW5.js → chunk-W4NT4IMI.js} +3 -3
- package/dist/{chunk-CVO2ZPW5.js.map → chunk-W4NT4IMI.js.map} +1 -1
- package/dist/{chunk-FGKWXSHF.cjs → chunk-XGYUUUHY.cjs} +22 -22
- package/dist/{chunk-FGKWXSHF.cjs.map → chunk-XGYUUUHY.cjs.map} +1 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/{ddl-wlEdaCQK.d.cts → ddl-B9lzB8Zi.d.cts} +3 -3
- package/dist/{ddl-DkFrUTn_.d.ts → ddl-DuZWvxBb.d.ts} +3 -3
- package/dist/graph-extension/index.d.cts +2 -2
- package/dist/graph-extension/index.d.ts +2 -2
- package/dist/graph-merge/index.cjs +31 -31
- package/dist/graph-merge/index.d.cts +7 -6
- package/dist/graph-merge/index.d.ts +7 -6
- package/dist/graph-merge/index.js +8 -8
- package/dist/{graph-templates-6zTU7bNe.d.cts → graph-templates-Buh-RlmQ.d.cts} +2 -2
- package/dist/{graph-templates-B4gkXVqg.d.ts → graph-templates-DQnmCPkd.d.ts} +2 -2
- package/dist/index.cjs +68 -68
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +8 -8
- package/dist/indexes/index.cjs +8 -8
- package/dist/indexes/index.d.cts +4 -4
- package/dist/indexes/index.d.ts +4 -4
- package/dist/indexes/index.js +3 -3
- package/dist/{ingestion-import-target-im9wEB00.d.cts → ingestion-import-target-BSgJagqI.d.cts} +1 -1
- package/dist/{ingestion-import-target-SopMSm-T.d.ts → ingestion-import-target-PNw10V4T.d.ts} +1 -1
- package/dist/interchange/index.cjs +27 -27
- package/dist/interchange/index.d.cts +7 -6
- package/dist/interchange/index.d.ts +7 -6
- package/dist/interchange/index.js +4 -4
- package/dist/{local-store-impl-FTGRP2V7.js → local-store-impl-EPUMDNQJ.js} +12 -12
- package/dist/{local-store-impl-FTGRP2V7.js.map → local-store-impl-EPUMDNQJ.js.map} +1 -1
- package/dist/{local-store-impl-ARNXBBSF.cjs → local-store-impl-GFBZBCTN.cjs} +15 -15
- package/dist/{local-store-impl-ARNXBBSF.cjs.map → local-store-impl-GFBZBCTN.cjs.map} +1 -1
- package/dist/{pglite-store-impl-CNQZYRBC.cjs → pglite-store-impl-DB4RRLB7.cjs} +15 -15
- package/dist/{pglite-store-impl-CNQZYRBC.cjs.map → pglite-store-impl-DB4RRLB7.cjs.map} +1 -1
- package/dist/{pglite-store-impl-NULC2IHH.js → pglite-store-impl-M5PWKN7Z.js} +12 -12
- package/dist/{pglite-store-impl-NULC2IHH.js.map → pglite-store-impl-M5PWKN7Z.js.map} +1 -1
- package/dist/{postgres-Dd3TrFku.d.ts → postgres-2FBMdOE_.d.ts} +3 -3
- package/dist/{postgres-CLPfTNYN.d.ts → postgres-BR3AeXm9.d.ts} +1 -1
- package/dist/{postgres-cLQPlKtp.d.cts → postgres-CRatyTVL.d.cts} +1 -1
- package/dist/{postgres-B4VD_rVy.d.cts → postgres-lbZf0zyg.d.cts} +3 -3
- package/dist/{profile-Co154QBx.d.ts → profile-BipG05-8.d.ts} +2 -2
- package/dist/{profile-BqThShR_.d.cts → profile-DKtvxVyA.d.cts} +2 -2
- package/dist/profiler/index.d.cts +8 -7
- package/dist/profiler/index.d.ts +8 -7
- package/dist/provenance/index.cjs.map +1 -1
- package/dist/provenance/index.d.cts +6 -5
- package/dist/provenance/index.d.ts +6 -5
- package/dist/provenance/index.js.map +1 -1
- package/dist/{repair-validity-windows-BLoClfCq.d.cts → repair-validity-windows-BnSHFIsR.d.cts} +1 -1
- package/dist/{repair-validity-windows-C__28ckL.d.ts → repair-validity-windows-DfRb4gZm.d.ts} +1 -1
- package/dist/{resolve-DgFSIK99.d.ts → resolve-BbjZDYTw.d.ts} +1 -1
- package/dist/{resolve-DSUxNIqw.d.cts → resolve-mLksuBg2.d.cts} +1 -1
- package/dist/schema/index.cjs +30 -30
- package/dist/schema/index.d.cts +7 -7
- package/dist/schema/index.d.ts +7 -7
- package/dist/schema/index.js +5 -5
- package/dist/{searchable-CZKn12eY.d.cts → searchable-BEAN91Ce.d.cts} +1 -1
- package/dist/{searchable-CUWWphQI.d.ts → searchable-Bg2lMPRm.d.ts} +1 -1
- package/dist/{sqlite-mSd_eVk4.d.ts → sqlite-Cal3rHgZ.d.ts} +3 -3
- package/dist/{sqlite-CoBmhiFd.d.ts → sqlite-CvajLABd.d.cts} +1 -1
- package/dist/{sqlite-qXLIybR2.d.cts → sqlite-DQxKoWAH.d.cts} +3 -3
- package/dist/{sqlite-RdH7w-ix.d.cts → sqlite-jH5J-Jb8.d.ts} +1 -1
- package/dist/{store-BzmMsCcw.d.ts → store-CvtRQ8Nb.d.cts} +136 -10
- package/dist/{store-CL6uTm_W.d.cts → store-sLu0hcRm.d.ts} +136 -10
- package/dist/{types-BUoh7cc3.d.cts → types-BUA3dZ99.d.cts} +1 -1
- package/dist/{types-ClC0IFIS.d.ts → types-CPtb7KNf.d.ts} +1 -1
- package/dist/{types-Blq8PG_N.d.ts → types-Dky3sCFz.d.cts} +9 -0
- package/dist/{types-Blq8PG_N.d.cts → types-Dky3sCFz.d.ts} +9 -0
- package/dist/{where-61C-QoM8.d.ts → where-BReEkAiy.d.ts} +1 -1
- package/dist/{where-o3Me5iJx.d.cts → where-Cz11nPRu.d.cts} +1 -1
- package/package.json +2 -2
- package/dist/chunk-4MZQVVPX.cjs.map +0 -1
- package/dist/chunk-7JUD57B4.js.map +0 -1
- package/dist/chunk-FHFPUORN.cjs.map +0 -1
- package/dist/chunk-YTYB5KCQ.js.map +0 -1
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { createEdgeRowMapper, createNodeRowMapper, SQLITE_ROW_MAPPER_CONFIG, POSTGRES_ROW_MAPPER_CONFIG, normalizeRowTimestamp, normalizeRequiredRowTimestamp, buildHardDeleteEdgeClaimsByNodeKind, buildHardDeleteUniquesByConcreteKind, buildHardDeleteEdgeClaimsByEdgeKind } from './chunk-EFTVYPGQ.js';
|
|
2
2
|
import { assertRecordedInstantOwnershipMatch, resolveRecordedTimeOwnership, requireRecordedTime, isEngineNativeRecordedReadBinding } from './chunk-7GZJ36LN.js';
|
|
3
|
-
import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDeleteBatch, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeReplacementBatch, prepareNodeReplacement, executeNodeResolvedMutationSet, executeNodeUpsertUpdateBatch, executeNodeSetUpdate, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, normalizePersistedEdgeMatchProps, assertValidityEndMutation, assertClearValidToSupported, buildEdgeMatchKey, resolveAtomicEdgeConvergenceExecutor, resolveEdgeMatchIdentityStorage, runHookedWritePlan, edgeWritePlan, resolveAtomicEdgeDeleteBatchExecutor, runWritePlan, runAtomicProgramWithHooks, unsupportedResolvedMutationSet, resolveAtomicEdgeResolvedMutationSetExecutor, withAlreadyExistsTranslation, ResolvedMutationSetMoved, appliedResolvedMutationSet, edgeWriteNeedsConstraintFence, writeResultAlwaysChanges, resolveAtomicEdgeBatchExecutor, nestedManagedWriteTarget, runResolvedMutationSetConverging, canonicalPersistedJsonValue, assertAtomicDeleteSchemaFenceMatched, edgeMatchIdentityUpdateRefusal, resolveAtomicEdgeResolvedUpdateBatchExecutor, atomicResolvedUpdateAttemptBudget, createEdgeBatchValidationBackend, canFuseSchemaFenceInFirstWrite, isAutocommitSingleStatementWrite, runAutocommitSingleStatementWritePlan, classifyDurableEdgeBatchOutcomes,
|
|
3
|
+
import { rowToNode, executeNodeBulkFindByIndex, executeNodeBulkFindByConstraint, executeNodeFindByConstraint, executeNodeBulkGetOrCreateByConstraint, executeNodeGetOrCreateByConstraint, executeNodeHardDelete, executeNodeDeleteBatch, executeNodeDelete, nodeUpsertDirtyCheck, executeNodeReplacementBatch, prepareNodeReplacement, executeNodeResolvedMutationSet, executeNodeUpsertUpdateBatch, executeNodeSetUpdate, executeNodeUpdate, executeNodeCreateNoReturnBatch, executeNodeCreateBatch, executeNodeCreate, rowToEdge, normalizePersistedEdgeMatchProps, assertValidityEndMutation, assertClearValidToSupported, buildEdgeMatchKey, resolveAtomicEdgeConvergenceExecutor, resolveEdgeMatchIdentityStorage, runHookedWritePlan, edgeWritePlan, resolveAtomicEdgeDeleteBatchExecutor, runWritePlan, runAtomicProgramWithHooks, unsupportedResolvedMutationSet, resolveAtomicEdgeResolvedMutationSetExecutor, withAlreadyExistsTranslation, ResolvedMutationSetMoved, appliedResolvedMutationSet, edgeWriteNeedsConstraintFence, writeResultAlwaysChanges, resolveAtomicEdgeBatchExecutor, nestedManagedWriteTarget, runResolvedMutationSetConverging, canonicalPersistedJsonValue, assertAtomicDeleteSchemaFenceMatched, edgeMatchIdentityUpdateRefusal, resolveAtomicEdgeResolvedUpdateBatchExecutor, atomicResolvedUpdateAttemptBudget, createEdgeBatchValidationBackend, canFuseSchemaFenceInFirstWrite, isAutocommitSingleStatementWrite, runAutocommitSingleStatementWritePlan, classifyDurableEdgeBatchOutcomes, rowToEdgeMeta, rowToNodeMeta, checkCardinalityConstraint, validityEndAfterMutation, assertsStoredWindowState, unfencedTarget, AutocommitWriteRequiresTransaction } from './chunk-V3JKR2CN.js';
|
|
4
4
|
import { applyResolvedNodeClaims, assertFulltextMember, getEmbeddingFields, computeFulltextContent } from './chunk-6BVZHDAZ.js';
|
|
5
5
|
import { isBundledRootAutocommitEligible } from './chunk-AHRNKPEV.js';
|
|
6
6
|
import { edgeCardinalityClaimTarget, edgeCardinalityClaimRefusal, edgeCardinalityClaim, edgeCardinalityClaimMode, claimEdgeCardinality } from './chunk-IM4X2ZOR.js';
|
|
7
7
|
import { resolveBackendFulltext } from './chunk-N535PWMA.js';
|
|
8
8
|
import { AtomicEdgeBatchEndpointRefusalError, AtomicEdgeConvergenceTombstoneRefusalError, AtomicEdgeDeleteIdentityRefusalError, AtomicEdgeBatchCardinalityRefusalError } from './chunk-2DNUADXX.js';
|
|
9
|
-
import { loadAndMergeGraphExtensionDocument, serializeSchema, buildKindRegistry, ensureIdentitySchemaStorage, loadAndVerifyGraph, identitySchemaCommitPreflight, getSchemaChanges, requiresMigration, mergeGraphExtension, commitNewSchemaVersion, commitNewSchemaVersionWithPreflight, parseSerializedSchema, planRemovals, stripGraphExtension, applyDeprecatedKinds, identityKindCascadeNeeded, ensureSchema, loadActiveSchemaWithBootstrap, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, commitNewSchemaVersionIfKindsEmpty, serializeIndexDeclaration } from './chunk-
|
|
9
|
+
import { loadAndMergeGraphExtensionDocument, serializeSchema, buildKindRegistry, ensureIdentitySchemaStorage, loadAndVerifyGraph, identitySchemaCommitPreflight, getSchemaChanges, requiresMigration, mergeGraphExtension, commitNewSchemaVersion, commitNewSchemaVersionWithPreflight, parseSerializedSchema, planRemovals, stripGraphExtension, applyDeprecatedKinds, identityKindCascadeNeeded, ensureSchema, loadActiveSchemaWithBootstrap, extensionKindNames, serializeSchemaProperties, buildGraphExtensionOntologyKeySet, compileTimeOntologyKey, commitNewSchemaVersionIfKindsEmpty, serializeIndexDeclaration } from './chunk-E6PU35DE.js';
|
|
10
10
|
import { countSchemaKindRows } from './chunk-RFMSZ7CF.js';
|
|
11
11
|
import { getTypeName } from './chunk-YXT3CCTR.js';
|
|
12
|
-
import { loadCurrentStructuralClasses, loadAssertionsByIds, toTransferAssertion, liveNodeKindsSharingIds, createIdentityFacade, createIdentityReadFacade, validateIdentityForContext, removeIdentityKindsForContext, readIdentityAssertionsForInterchange, readIdentityAssertionPageAtTarget, lockIdentityGraph, foldIdentityForCreatedNodes, importIdentityAssertionsIntoTarget, assertAffectedIdentityClassesConsistent, applyIdentityChangesForContext, refKey, requireNodeValidityEndCompatible, detachIdentityForNode, rebuildIdentityClosureForContext, assertEdgeMatchIdentityBackendSupport } from './chunk-
|
|
12
|
+
import { loadCurrentStructuralClasses, loadAssertionsByIds, toTransferAssertion, liveNodeKindsSharingIds, createIdentityFacade, createIdentityReadFacade, validateIdentityForContext, removeIdentityKindsForContext, readIdentityAssertionsForInterchange, readIdentityAssertionPageAtTarget, lockIdentityGraph, foldIdentityForCreatedNodes, importIdentityAssertionsIntoTarget, assertAffectedIdentityClassesConsistent, applyIdentityChangesForContext, refKey, requireNodeValidityEndCompatible, detachIdentityForNode, rebuildIdentityClosureForContext, assertEdgeMatchIdentityBackendSupport } from './chunk-W4NT4IMI.js';
|
|
13
13
|
import { storeRuntime, STORE_RUNTIME, assertRevisionTrackableBackend, createRecordedBackend, lockRecordedGraphWrite, refuseEngineNativeRecordedIdentityRead, createRecordedTransactionScope, readRecordedClock, ensureRevisionOrigin, recordedCaptureRequiresCallbackTransactionError, assertRecordedCaptureTransactionIsolation, lockSchemaVersionForStoreWrite, createMutationWitness, registerRecordedIdentityMutationWitness, TRANSACTION_RUNTIME, mintsOriginNamespacedAnchor, ensureRevisionOriginsRelation, generateId, runInWriteTransaction, assertCurrentRecordedSchema, AUTO_REFRESH_STATISTICS_ROW_THRESHOLD, withRecordedFlushObserver, withTransactionSchemaFenceLease, withWriteTransactionSession, resetRevisionOrigin, advanceRevisionClock, validateEdgeProps, diagnoseFusedSchemaFenceNoRow, getEdgeRowsByIds, memoizeLeasedSchemaFence, getNodeRowsByIds, hasLeasedSchemaFence, closeRecordedHardDeletedKind, historicalIdentityPeerClassQuery, IDENTITY_PEER_CLASS_COLUMNS, recordedBindParamBudget, throwHistoryUnsafeSqlAccess, throwRevisionTrackingUnsafeSqlAccess } from './chunk-HWWPL2YL.js';
|
|
14
14
|
import { isParameterRef, resolveParameterValueType, fieldRef, buildFieldBuilderForTypeInfo, stringField, createFulltextAccessor, CURRENT_READ_INSTANT_PLACEHOLDER, extractFulltextMatchPredicates, extractVectorSimilarityPredicates, withPinnedReadInstant, resolveBatchWriteVerdict, batchRefusalSuffix, batchRefusalDetails, canonicalEqual, runRetriedUnit, assertRecursiveTraversalSupported, baseField, objectField, arrayField, dateField, numberField, sortedReplacer, compileFieldValue, compileKindFilter, compileTemporalFilter, currentReadInstant, chunk, sqlValueList, buildPredicateIndex, requireRecursiveTraversalVerdict, getFieldPointer, groupBy, delay, currentReadInstantFor, extractTemporalOptions, compilePredicateExpression, isOptimisticRetryTier, OPTIMISTIC_RETRY_ATTEMPTS, getPredicatesForAlias, getNodeKindsForAlias, getHybridTargetAlias, compilePredicateClauses } from './chunk-XWMB3AFN.js';
|
|
15
15
|
import { batchPointReadVerdict, statementExecutionVerdict, createClaimsVerdictThunk, uniqueSidecarBatchVerdict, contributionHealthVerdict, recordedRevisionOriginsVerdict, requireExtras, requireCatalog } from './chunk-ZQIDQHDR.js';
|
|
16
|
-
import { assumeRecursiveTraversalSupported, withRecordedRelationsPrecondition, createSqlSchema, requireSqlSchema, DEFAULT_SQL_SCHEMA, recordedReadSchemaFor, resolveRecursiveTraversal, resolveWriteFencePlan, refuseUnfencedOperationalIdentity, refuseUnfencedClockAllocation, requireExternalRecordedReadSource, createRecordedReadBinding, createEngineRecordedReadBinding, runOptionallyInTransaction, createTransactionReadBackend, bindExtraIfReachable, BATCH_POINT_READ, CONTRIBUTION_HEALTH, bindExtra, projectGraphBackend, deriveBackend, vectorSlotKey, requireRecordedReadBinding, projectBackend, rowPropsToObject,
|
|
16
|
+
import { assumeRecursiveTraversalSupported, withRecordedRelationsPrecondition, createSqlSchema, requireSqlSchema, DEFAULT_SQL_SCHEMA, recordedReadSchemaFor, resolveRecursiveTraversal, resolveWriteFencePlan, refuseUnfencedOperationalIdentity, refuseUnfencedClockAllocation, requireExternalRecordedReadSource, createRecordedReadBinding, createEngineRecordedReadBinding, runOptionallyInTransaction, createTransactionReadBackend, bindExtraIfReachable, BATCH_POINT_READ, CONTRIBUTION_HEALTH, bindExtra, projectGraphBackend, deriveBackend, vectorSlotKey, requireRecordedReadBinding, projectBackend, rowPropsToObject, recordedReadSqlSchema, INTERNAL_TEMPORARY_WRITES, postgresReadWriteRefusedSqlState, assertGraphCommandConvergenceIsolation, isSchemaFencedInsertEligible, executeAuthoritativeGraphCommand, assertRecursiveTraversal, isMissingTableError, postgresTemporaryTableUnavailableSqlState, isPostgresConcurrentDdlRaceError, ALIAS_CTE_PREFIX, EMBEDDINGS_CTE_ALIAS, FULLTEXT_CTE_ALIAS, HYBRID_CANDIDATES_CTE_ALIAS } from './chunk-LI7JGO5B.js';
|
|
17
17
|
import { isKnownKind } from './chunk-CYSXF3PS.js';
|
|
18
18
|
import { isEdgeTargetMap, projectTargetKinds, validateEdgeEndpoints, compareClaimTargets, encodeTupleKey, uniquenessClaimTarget, subClassComponent, isSameClaimOwner, DISJOINT_CONSTRAINT_NAME, disjointnessClaimAxis } from './chunk-WUNSJGP6.js';
|
|
19
19
|
import { resolveReadCoordinate, withRecordedCoordinate, describeCoordinate, coordinateContext, nowIso, recordedInstantWallTime, asRecordedInstant, createEngineRecordedInstant, validityWindowContainsInstant, validateStatedValidityLowerBound, validateOptionalCanonicalIsoDate, assertOrderedValidityWindow, preservesImmutableLowerBound, parseRecordedInstant, assertWritableValidityWindow, assertValidRecordedInstant, optionalRecordedInstantParts, isCanonicalIsoDate, statedBoundMatchesStored } from './chunk-6TIDSIPH.js';
|
|
20
|
-
import { generateIndexDDL } from './chunk-
|
|
20
|
+
import { generateIndexDDL } from './chunk-LOFUF6L7.js';
|
|
21
21
|
import { SYSTEM_INDEX_DECLARATIONS, resolveSystemIndexTableName, systemIndexName, resolveSystemIndexNames, generateSystemIndexDDL } from './chunk-JANTPNIZ.js';
|
|
22
|
-
import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-
|
|
22
|
+
import { NODE_META_KEYS, EDGE_META_KEYS } from './chunk-2QNFFAMF.js';
|
|
23
23
|
import { sha256Hex, fnv1aBase36 } from './chunk-K34OPSJK.js';
|
|
24
|
-
import { getDialect } from './chunk-
|
|
24
|
+
import { getDialect } from './chunk-OH7QRGPQ.js';
|
|
25
25
|
import { DEFAULT_PAGINATION_LIMIT, DEFAULT_STREAM_BATCH_SIZE, SQLITE_PATH_DELIMITER, PG_ARRAY_START, PG_ARRAY_END, PG_PATH_ELEMENT_SEPARATOR, MAX_PG_IDENTIFIER_LENGTH } from './chunk-2EBMPJBO.js';
|
|
26
26
|
import { assertVectorMinScore, assertApproximateMetricSupported, vectorScoreExpression, vectorMinScoreCondition } from './chunk-3MZTAXYX.js';
|
|
27
27
|
import { isSqlPlaceholder, bindSqlValue, asCompiledSelectSql, sql, markAnnIndexScan, isRawExecutable, renderSql, annIndexScanTypes, asCompiledRowsSql, markForceCustomPlan, asCompiledStatementSql, asCompiledTemporaryStatementSql } from './chunk-CIYUFNZ6.js';
|
|
@@ -3473,6 +3473,344 @@ function decodeByValueType(value, valueType) {
|
|
|
3473
3473
|
}
|
|
3474
3474
|
}
|
|
3475
3475
|
|
|
3476
|
+
// src/store/neighbors.ts
|
|
3477
|
+
var NEIGHBOR_ORDER_FIELDS = [
|
|
3478
|
+
"createdAt",
|
|
3479
|
+
"id",
|
|
3480
|
+
"updatedAt",
|
|
3481
|
+
"validFrom",
|
|
3482
|
+
"validTo"
|
|
3483
|
+
];
|
|
3484
|
+
var NEIGHBOR_ORDER_FIELD_SET = new Set(
|
|
3485
|
+
NEIGHBOR_ORDER_FIELDS
|
|
3486
|
+
);
|
|
3487
|
+
function isNeighborOrderField(field2) {
|
|
3488
|
+
return NEIGHBOR_ORDER_FIELD_SET.has(field2);
|
|
3489
|
+
}
|
|
3490
|
+
function mapNeighborCountRows(rows) {
|
|
3491
|
+
return Number(rows[0]?.["count"] ?? 0);
|
|
3492
|
+
}
|
|
3493
|
+
function createNeighborRead(ctx, source, options) {
|
|
3494
|
+
validateOptions(ctx, options);
|
|
3495
|
+
const query = buildNeighborQuery(ctx, source, options, false);
|
|
3496
|
+
function mapRows(rows) {
|
|
3497
|
+
return rows.map((row) => ({
|
|
3498
|
+
edge: mapEdge(row),
|
|
3499
|
+
node: mapNode(row)
|
|
3500
|
+
}));
|
|
3501
|
+
}
|
|
3502
|
+
return {
|
|
3503
|
+
execute: async () => {
|
|
3504
|
+
if (options.edges.length === 0) return [];
|
|
3505
|
+
return mapRows(
|
|
3506
|
+
await ctx.backend.execute(asCompiledRowsSql(query))
|
|
3507
|
+
);
|
|
3508
|
+
},
|
|
3509
|
+
compileOneStatementBatchItem: () => ({
|
|
3510
|
+
query: asCompiledRowsSql(query),
|
|
3511
|
+
outputNames: neighborOutputNames(),
|
|
3512
|
+
orderBy: neighborBatchOrder(options.orderBy),
|
|
3513
|
+
mapRows
|
|
3514
|
+
})
|
|
3515
|
+
};
|
|
3516
|
+
}
|
|
3517
|
+
async function readNeighbors(ctx, source, options) {
|
|
3518
|
+
return createNeighborRead(ctx, source, options).execute();
|
|
3519
|
+
}
|
|
3520
|
+
async function countNeighbors(ctx, source, options) {
|
|
3521
|
+
return createNeighborCountRead(ctx, source, options).execute();
|
|
3522
|
+
}
|
|
3523
|
+
function createNeighborCountRead(ctx, source, options) {
|
|
3524
|
+
validateEdgeReadBounds(options, "countNeighbors");
|
|
3525
|
+
const query = buildNeighborQuery(ctx, source, options, true);
|
|
3526
|
+
return {
|
|
3527
|
+
execute: async () => {
|
|
3528
|
+
if (options.edges.length === 0) return 0;
|
|
3529
|
+
return mapNeighborCountRows(
|
|
3530
|
+
await ctx.backend.execute(asCompiledRowsSql(query))
|
|
3531
|
+
);
|
|
3532
|
+
},
|
|
3533
|
+
compileOneStatementBatchItem: () => ({
|
|
3534
|
+
query: asCompiledRowsSql(query),
|
|
3535
|
+
outputNames: ["count"],
|
|
3536
|
+
orderBy: [],
|
|
3537
|
+
mapRows: mapNeighborCountRows
|
|
3538
|
+
})
|
|
3539
|
+
};
|
|
3540
|
+
}
|
|
3541
|
+
function buildNeighborQuery(ctx, source, options, aggregate) {
|
|
3542
|
+
const direction = options.direction ?? "out";
|
|
3543
|
+
const instant = currentReadInstant();
|
|
3544
|
+
const temporalMode = options.temporalMode ?? ctx.defaultTemporalMode;
|
|
3545
|
+
const edgeTemporal = compileTemporalFilter({
|
|
3546
|
+
mode: temporalMode,
|
|
3547
|
+
asOf: options.asOf,
|
|
3548
|
+
tableAlias: "e",
|
|
3549
|
+
currentTimestamp: instant
|
|
3550
|
+
});
|
|
3551
|
+
const nodeTemporal = compileTemporalFilter({
|
|
3552
|
+
mode: temporalMode,
|
|
3553
|
+
asOf: options.asOf,
|
|
3554
|
+
tableAlias: "n",
|
|
3555
|
+
currentTimestamp: instant
|
|
3556
|
+
});
|
|
3557
|
+
const endpoint = endpointClauses(direction, source);
|
|
3558
|
+
const where = sql.join(
|
|
3559
|
+
[
|
|
3560
|
+
sql`e.graph_id = ${ctx.graphId}`,
|
|
3561
|
+
sql`n.graph_id = ${ctx.graphId}`,
|
|
3562
|
+
compileKindFilter(sql.raw("e.kind"), options.edges),
|
|
3563
|
+
edgeTemporal,
|
|
3564
|
+
nodeTemporal,
|
|
3565
|
+
endpoint.filter
|
|
3566
|
+
],
|
|
3567
|
+
sql` AND `
|
|
3568
|
+
);
|
|
3569
|
+
if (aggregate) {
|
|
3570
|
+
return sql`SELECT COUNT(DISTINCT e.id) AS count FROM ${ctx.schema.edgesTable} e JOIN ${ctx.schema.nodesTable} n ON ${endpoint.join} WHERE ${where}`;
|
|
3571
|
+
}
|
|
3572
|
+
const orderValue = buildOrderValue(ctx, options.orderBy);
|
|
3573
|
+
const order = buildOrder(options.orderBy, orderValue);
|
|
3574
|
+
const limit = options.limit === void 0 ? sql.empty() : sql` LIMIT ${options.limit}`;
|
|
3575
|
+
return sql`SELECT ${neighborColumns()}, ${orderValue} AS typegraph_neighbor_order FROM ${ctx.schema.edgesTable} e JOIN ${ctx.schema.nodesTable} n ON ${endpoint.join} WHERE ${where} ORDER BY ${order}${limit}`;
|
|
3576
|
+
}
|
|
3577
|
+
function endpointClauses(direction, source) {
|
|
3578
|
+
const outgoingFilter = sql`e.from_kind = ${source.kind} AND e.from_id = ${source.id}`;
|
|
3579
|
+
const incomingFilter = sql`e.to_kind = ${source.kind} AND e.to_id = ${source.id}`;
|
|
3580
|
+
switch (direction) {
|
|
3581
|
+
case "out": {
|
|
3582
|
+
return {
|
|
3583
|
+
filter: outgoingFilter,
|
|
3584
|
+
join: sql`n.kind = e.to_kind AND n.id = e.to_id`
|
|
3585
|
+
};
|
|
3586
|
+
}
|
|
3587
|
+
case "in": {
|
|
3588
|
+
return {
|
|
3589
|
+
filter: incomingFilter,
|
|
3590
|
+
join: sql`n.kind = e.from_kind AND n.id = e.from_id`
|
|
3591
|
+
};
|
|
3592
|
+
}
|
|
3593
|
+
case "both": {
|
|
3594
|
+
return {
|
|
3595
|
+
filter: sql`((${outgoingFilter}) OR (${incomingFilter}))`,
|
|
3596
|
+
join: sql`((e.from_kind = ${source.kind} AND e.from_id = ${source.id} AND n.kind = e.to_kind AND n.id = e.to_id) OR (e.to_kind = ${source.kind} AND e.to_id = ${source.id} AND n.kind = e.from_kind AND n.id = e.from_id))`
|
|
3597
|
+
};
|
|
3598
|
+
}
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
function edgeOrderColumnName(field2) {
|
|
3602
|
+
switch (field2) {
|
|
3603
|
+
case "id": {
|
|
3604
|
+
return "id";
|
|
3605
|
+
}
|
|
3606
|
+
case "createdAt": {
|
|
3607
|
+
return "created_at";
|
|
3608
|
+
}
|
|
3609
|
+
case "updatedAt": {
|
|
3610
|
+
return "updated_at";
|
|
3611
|
+
}
|
|
3612
|
+
case "validFrom": {
|
|
3613
|
+
return "valid_from";
|
|
3614
|
+
}
|
|
3615
|
+
case "validTo": {
|
|
3616
|
+
return "valid_to";
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
function buildOrderValue(ctx, orderBy) {
|
|
3621
|
+
if (orderBy?.by !== "node") {
|
|
3622
|
+
return sql`e.${sql.raw(edgeOrderColumnName(orderBy?.field ?? "id"))}`;
|
|
3623
|
+
}
|
|
3624
|
+
return compileTypedJsonExtract({
|
|
3625
|
+
column: sql.raw("n.props"),
|
|
3626
|
+
dialect: getDialect(ctx.backend.dialect),
|
|
3627
|
+
fallback: "text",
|
|
3628
|
+
pointer: jsonPointer([orderBy.field]),
|
|
3629
|
+
valueType: resolveNodeOrderFieldType(ctx, orderBy.field)?.valueType
|
|
3630
|
+
});
|
|
3631
|
+
}
|
|
3632
|
+
function buildOrder(orderBy, value) {
|
|
3633
|
+
const direction = orderBy?.direction ?? "asc";
|
|
3634
|
+
return sql`CASE WHEN ${value} IS NULL THEN 1 ELSE 0 END ASC, ${value} ${sql.raw(direction.toUpperCase())}, e.id ASC`;
|
|
3635
|
+
}
|
|
3636
|
+
function neighborBatchOrder(orderBy) {
|
|
3637
|
+
return [
|
|
3638
|
+
{
|
|
3639
|
+
column: "typegraph_neighbor_order",
|
|
3640
|
+
direction: orderBy?.direction ?? "asc",
|
|
3641
|
+
nulls: "last"
|
|
3642
|
+
},
|
|
3643
|
+
{ column: "edge_id", direction: "asc", nulls: "last" }
|
|
3644
|
+
];
|
|
3645
|
+
}
|
|
3646
|
+
function validateOptions(ctx, options) {
|
|
3647
|
+
validateEdgeReadBounds(options, "neighbors");
|
|
3648
|
+
if (options.orderBy?.by !== "node") return;
|
|
3649
|
+
resolveNodeOrderFieldType(ctx, options.orderBy.field);
|
|
3650
|
+
}
|
|
3651
|
+
function resolveNodeOrderFieldType(ctx, field2) {
|
|
3652
|
+
const nodeKinds = [...ctx.registry.nodeKinds.keys()];
|
|
3653
|
+
const introspector = createSchemaIntrospector(ctx.registry.nodeKinds);
|
|
3654
|
+
const declaringKinds = nodeKinds.filter(
|
|
3655
|
+
(kind) => introspector.getFieldTypeInfo(kind, field2) !== void 0
|
|
3656
|
+
);
|
|
3657
|
+
if (declaringKinds.length === 0) {
|
|
3658
|
+
throw new ValidationError("Unknown adjacent-node ordering field", {
|
|
3659
|
+
issues: [{ path: "neighbors.orderBy.field", message: "Invalid field" }]
|
|
3660
|
+
});
|
|
3661
|
+
}
|
|
3662
|
+
return introspector.getSharedFieldTypeInfo(declaringKinds, field2);
|
|
3663
|
+
}
|
|
3664
|
+
function validateEdgeReadBounds(options, path) {
|
|
3665
|
+
if (options.limit !== void 0 && (!Number.isSafeInteger(options.limit) || options.limit <= 0)) {
|
|
3666
|
+
throw new ValidationError(
|
|
3667
|
+
"Neighbor limit must be a positive safe integer",
|
|
3668
|
+
{
|
|
3669
|
+
issues: [{ path: `${path}.limit`, message: "Invalid edge-read limit" }]
|
|
3670
|
+
}
|
|
3671
|
+
);
|
|
3672
|
+
}
|
|
3673
|
+
if (options.direction !== void 0 && options.direction !== "both" && options.direction !== "in" && options.direction !== "out") {
|
|
3674
|
+
throw new ValidationError("Unknown edge traversal direction", {
|
|
3675
|
+
issues: [{ path: `${path}.direction`, message: "Invalid direction" }]
|
|
3676
|
+
});
|
|
3677
|
+
}
|
|
3678
|
+
const field2 = options.orderBy?.field;
|
|
3679
|
+
if (field2 !== void 0 && options.orderBy?.by !== "node" && !isNeighborOrderField(field2)) {
|
|
3680
|
+
throw new ValidationError("Unknown edge ordering field", {
|
|
3681
|
+
issues: [{ path: `${path}.orderBy.field`, message: "Invalid field" }]
|
|
3682
|
+
});
|
|
3683
|
+
}
|
|
3684
|
+
const direction = options.orderBy?.direction;
|
|
3685
|
+
if (direction !== void 0 && direction !== "asc" && direction !== "desc") {
|
|
3686
|
+
throw new ValidationError("Unknown edge ordering direction", {
|
|
3687
|
+
issues: [
|
|
3688
|
+
{ path: `${path}.orderBy.direction`, message: "Invalid direction" }
|
|
3689
|
+
]
|
|
3690
|
+
});
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
function neighborColumns() {
|
|
3694
|
+
const edgeColumns = [
|
|
3695
|
+
"graph_id",
|
|
3696
|
+
"id",
|
|
3697
|
+
"kind",
|
|
3698
|
+
"from_kind",
|
|
3699
|
+
"from_id",
|
|
3700
|
+
"to_kind",
|
|
3701
|
+
"to_id",
|
|
3702
|
+
"props",
|
|
3703
|
+
"valid_from",
|
|
3704
|
+
"valid_to",
|
|
3705
|
+
"created_at",
|
|
3706
|
+
"updated_at",
|
|
3707
|
+
"deleted_at"
|
|
3708
|
+
];
|
|
3709
|
+
const nodeColumns = [
|
|
3710
|
+
"graph_id",
|
|
3711
|
+
"id",
|
|
3712
|
+
"kind",
|
|
3713
|
+
"props",
|
|
3714
|
+
"version",
|
|
3715
|
+
"valid_from",
|
|
3716
|
+
"valid_to",
|
|
3717
|
+
"created_at",
|
|
3718
|
+
"updated_at",
|
|
3719
|
+
"deleted_at"
|
|
3720
|
+
];
|
|
3721
|
+
return sql.join(
|
|
3722
|
+
[
|
|
3723
|
+
...edgeColumns.map(
|
|
3724
|
+
(column) => sql`e.${sql.raw(column)} AS ${sql.identifier(`edge_${column}`)}`
|
|
3725
|
+
),
|
|
3726
|
+
...nodeColumns.map(
|
|
3727
|
+
(column) => sql`n.${sql.raw(column)} AS ${sql.identifier(`node_${column}`)}`
|
|
3728
|
+
)
|
|
3729
|
+
],
|
|
3730
|
+
sql`, `
|
|
3731
|
+
);
|
|
3732
|
+
}
|
|
3733
|
+
function neighborOutputNames() {
|
|
3734
|
+
return [
|
|
3735
|
+
"edge_graph_id",
|
|
3736
|
+
"edge_id",
|
|
3737
|
+
"edge_kind",
|
|
3738
|
+
"edge_from_kind",
|
|
3739
|
+
"edge_from_id",
|
|
3740
|
+
"edge_to_kind",
|
|
3741
|
+
"edge_to_id",
|
|
3742
|
+
"edge_props",
|
|
3743
|
+
"edge_valid_from",
|
|
3744
|
+
"edge_valid_to",
|
|
3745
|
+
"edge_created_at",
|
|
3746
|
+
"edge_updated_at",
|
|
3747
|
+
"edge_deleted_at",
|
|
3748
|
+
"node_graph_id",
|
|
3749
|
+
"node_id",
|
|
3750
|
+
"node_kind",
|
|
3751
|
+
"node_props",
|
|
3752
|
+
"node_version",
|
|
3753
|
+
"node_valid_from",
|
|
3754
|
+
"node_valid_to",
|
|
3755
|
+
"node_created_at",
|
|
3756
|
+
"node_updated_at",
|
|
3757
|
+
"node_deleted_at"
|
|
3758
|
+
];
|
|
3759
|
+
}
|
|
3760
|
+
function mapEdge(row) {
|
|
3761
|
+
return rowToEdge({
|
|
3762
|
+
id: String(row["edge_id"]),
|
|
3763
|
+
kind: String(row["edge_kind"]),
|
|
3764
|
+
from_kind: String(row["edge_from_kind"]),
|
|
3765
|
+
from_id: String(row["edge_from_id"]),
|
|
3766
|
+
to_kind: String(row["edge_to_kind"]),
|
|
3767
|
+
to_id: String(row["edge_to_id"]),
|
|
3768
|
+
props: row["edge_props"],
|
|
3769
|
+
valid_from: normalizeRowTimestamp(
|
|
3770
|
+
row["edge_valid_from"],
|
|
3771
|
+
"edge_valid_from"
|
|
3772
|
+
),
|
|
3773
|
+
valid_to: normalizeRowTimestamp(row["edge_valid_to"], "edge_valid_to"),
|
|
3774
|
+
created_at: normalizeRequiredRowTimestamp(
|
|
3775
|
+
row["edge_created_at"],
|
|
3776
|
+
"edge_created_at"
|
|
3777
|
+
),
|
|
3778
|
+
updated_at: normalizeRequiredRowTimestamp(
|
|
3779
|
+
row["edge_updated_at"],
|
|
3780
|
+
"edge_updated_at"
|
|
3781
|
+
),
|
|
3782
|
+
deleted_at: normalizeRowTimestamp(
|
|
3783
|
+
row["edge_deleted_at"],
|
|
3784
|
+
"edge_deleted_at"
|
|
3785
|
+
)
|
|
3786
|
+
});
|
|
3787
|
+
}
|
|
3788
|
+
function mapNode(row) {
|
|
3789
|
+
return rowToNode({
|
|
3790
|
+
id: String(row["node_id"]),
|
|
3791
|
+
kind: String(row["node_kind"]),
|
|
3792
|
+
props: row["node_props"],
|
|
3793
|
+
version: Number(row["node_version"]),
|
|
3794
|
+
valid_from: normalizeRowTimestamp(
|
|
3795
|
+
row["node_valid_from"],
|
|
3796
|
+
"node_valid_from"
|
|
3797
|
+
),
|
|
3798
|
+
valid_to: normalizeRowTimestamp(row["node_valid_to"], "node_valid_to"),
|
|
3799
|
+
created_at: normalizeRequiredRowTimestamp(
|
|
3800
|
+
row["node_created_at"],
|
|
3801
|
+
"node_created_at"
|
|
3802
|
+
),
|
|
3803
|
+
updated_at: normalizeRequiredRowTimestamp(
|
|
3804
|
+
row["node_updated_at"],
|
|
3805
|
+
"node_updated_at"
|
|
3806
|
+
),
|
|
3807
|
+
deleted_at: normalizeRowTimestamp(
|
|
3808
|
+
row["node_deleted_at"],
|
|
3809
|
+
"node_deleted_at"
|
|
3810
|
+
)
|
|
3811
|
+
});
|
|
3812
|
+
}
|
|
3813
|
+
|
|
3476
3814
|
// src/store/recursive-cte.ts
|
|
3477
3815
|
function buildReachableCte(options) {
|
|
3478
3816
|
assertRecursiveTraversal(options.recursiveTraversal, options.operation);
|
|
@@ -3504,6 +3842,9 @@ function buildReachableCte(options) {
|
|
|
3504
3842
|
options.recordedReadBinding,
|
|
3505
3843
|
"recorded-recursive-cte"
|
|
3506
3844
|
);
|
|
3845
|
+
const edgeWindows = Object.entries(options.edgeWindows ?? {}).filter(
|
|
3846
|
+
(entry2) => entry2[1] !== void 0
|
|
3847
|
+
);
|
|
3507
3848
|
const initialPath = trackPath ? options.dialect.initializePath(sql.raw("n.id")) : void 0;
|
|
3508
3849
|
const pathExtension = trackPath ? options.dialect.extendPath(sql.raw("r.path"), sql.raw("n.id")) : void 0;
|
|
3509
3850
|
const cycleCheck = options.cyclePolicy === "prevent" ? options.dialect.cycleCheck(sql.raw("n.id"), sql.raw("r.path")) : void 0;
|
|
@@ -3529,14 +3870,34 @@ function buildReachableCte(options) {
|
|
|
3529
3870
|
];
|
|
3530
3871
|
if (cycleCheck !== void 0) recursiveWhere.push(cycleCheck);
|
|
3531
3872
|
const forceWorktableOuterJoinOrder = options.dialect.capabilities.forceRecursiveWorktableOuterJoinOrder;
|
|
3873
|
+
const usesOrientedEdges = edgeWindows.length > 0;
|
|
3532
3874
|
const recursiveCase = compileRecursiveBranch({
|
|
3533
3875
|
recursiveColumns,
|
|
3534
3876
|
whereClauses: recursiveWhere,
|
|
3535
|
-
direction: options.direction,
|
|
3877
|
+
direction: usesOrientedEdges ? "out" : options.direction,
|
|
3536
3878
|
forceWorktableOuterJoinOrder,
|
|
3537
|
-
schema
|
|
3879
|
+
schema,
|
|
3880
|
+
edgesTable: usesOrientedEdges ? sql.identifier("typegraph_windowed_edges") : schema.edgesTable,
|
|
3881
|
+
...usesOrientedEdges && {
|
|
3882
|
+
joinField: "typegraph_source_id",
|
|
3883
|
+
targetField: "typegraph_target_id",
|
|
3884
|
+
targetKindField: "typegraph_target_kind"
|
|
3885
|
+
}
|
|
3538
3886
|
});
|
|
3539
|
-
|
|
3887
|
+
const windowedEdges = usesOrientedEdges ? buildWindowedEdgesCte(
|
|
3888
|
+
schema.edgesTable,
|
|
3889
|
+
options.direction,
|
|
3890
|
+
options.edgeKinds.map((kind) => [kind, options.edgeWindows?.[kind]]),
|
|
3891
|
+
sql.join(
|
|
3892
|
+
[
|
|
3893
|
+
sql`e.graph_id = ${options.graphId}`,
|
|
3894
|
+
edgeKindFilter,
|
|
3895
|
+
edgeTemporalFilter
|
|
3896
|
+
],
|
|
3897
|
+
sql` AND `
|
|
3898
|
+
)
|
|
3899
|
+
) : void 0;
|
|
3900
|
+
return windowedEdges === void 0 ? sql`WITH RECURSIVE reachable AS (${baseCase} UNION ALL ${recursiveCase})` : sql`WITH RECURSIVE typegraph_windowed_edges AS (${windowedEdges}), reachable AS (${baseCase} UNION ALL ${recursiveCase})`;
|
|
3540
3901
|
}
|
|
3541
3902
|
function compileRecursiveBranch(options) {
|
|
3542
3903
|
const selectClause = sql`SELECT ${sql.join([...options.recursiveColumns], sql`, `)}`;
|
|
@@ -3545,11 +3906,12 @@ function compileRecursiveBranch(options) {
|
|
|
3545
3906
|
return buildDirectionalBranch({
|
|
3546
3907
|
selectClause,
|
|
3547
3908
|
whereClauses: options.whereClauses,
|
|
3548
|
-
joinField: "from_id",
|
|
3549
|
-
targetField: "to_id",
|
|
3550
|
-
targetKindField: "to_kind",
|
|
3909
|
+
joinField: options.joinField ?? "from_id",
|
|
3910
|
+
targetField: options.targetField ?? "to_id",
|
|
3911
|
+
targetKindField: options.targetKindField ?? "to_kind",
|
|
3551
3912
|
forceWorktableOuterJoinOrder: options.forceWorktableOuterJoinOrder,
|
|
3552
|
-
schema: options.schema
|
|
3913
|
+
schema: options.schema,
|
|
3914
|
+
edgesTable: options.edgesTable
|
|
3553
3915
|
});
|
|
3554
3916
|
}
|
|
3555
3917
|
case "in": {
|
|
@@ -3560,7 +3922,8 @@ function compileRecursiveBranch(options) {
|
|
|
3560
3922
|
targetField: "from_id",
|
|
3561
3923
|
targetKindField: "from_kind",
|
|
3562
3924
|
forceWorktableOuterJoinOrder: options.forceWorktableOuterJoinOrder,
|
|
3563
|
-
schema: options.schema
|
|
3925
|
+
schema: options.schema,
|
|
3926
|
+
edgesTable: options.edgesTable
|
|
3564
3927
|
});
|
|
3565
3928
|
}
|
|
3566
3929
|
case "both": {
|
|
@@ -3568,7 +3931,8 @@ function compileRecursiveBranch(options) {
|
|
|
3568
3931
|
selectClause,
|
|
3569
3932
|
whereClauses: options.whereClauses,
|
|
3570
3933
|
forceWorktableOuterJoinOrder: options.forceWorktableOuterJoinOrder,
|
|
3571
|
-
schema: options.schema
|
|
3934
|
+
schema: options.schema,
|
|
3935
|
+
edgesTable: options.edgesTable
|
|
3572
3936
|
});
|
|
3573
3937
|
}
|
|
3574
3938
|
}
|
|
@@ -3580,9 +3944,9 @@ function buildDirectionalBranch(options) {
|
|
|
3580
3944
|
...options.whereClauses,
|
|
3581
3945
|
sql`e.${sql.raw(options.joinField)} = r.id`
|
|
3582
3946
|
];
|
|
3583
|
-
return sql`${options.selectClause} FROM reachable r CROSS JOIN ${options.
|
|
3947
|
+
return sql`${options.selectClause} FROM reachable r CROSS JOIN ${options.edgesTable} e ${nodeJoin} WHERE ${sql.join(allWhere, sql` AND `)}`;
|
|
3584
3948
|
}
|
|
3585
|
-
return sql`${options.selectClause} FROM reachable r JOIN ${options.
|
|
3949
|
+
return sql`${options.selectClause} FROM reachable r JOIN ${options.edgesTable} e ON e.${sql.raw(options.joinField)} = r.id ${nodeJoin} WHERE ${sql.join([...options.whereClauses], sql` AND `)}`;
|
|
3586
3950
|
}
|
|
3587
3951
|
function buildBidirectionalBranch(options) {
|
|
3588
3952
|
const nodeJoin = sql`JOIN ${options.schema.nodesTable} n ON n.graph_id = e.graph_id AND ((e.to_id = r.id AND n.id = e.from_id AND n.kind = e.from_kind) OR (e.from_id = r.id AND n.id = e.to_id AND n.kind = e.to_kind))`;
|
|
@@ -3591,9 +3955,32 @@ function buildBidirectionalBranch(options) {
|
|
|
3591
3955
|
...options.whereClauses,
|
|
3592
3956
|
sql`(e.from_id = r.id OR e.to_id = r.id)`
|
|
3593
3957
|
];
|
|
3594
|
-
return sql`${options.selectClause} FROM reachable r CROSS JOIN ${options.
|
|
3595
|
-
}
|
|
3596
|
-
return sql`${options.selectClause} FROM reachable r JOIN ${options.
|
|
3958
|
+
return sql`${options.selectClause} FROM reachable r CROSS JOIN ${options.edgesTable} e ${nodeJoin} WHERE ${sql.join(allWhere, sql` AND `)}`;
|
|
3959
|
+
}
|
|
3960
|
+
return sql`${options.selectClause} FROM reachable r JOIN ${options.edgesTable} e ON (e.from_id = r.id OR e.to_id = r.id) ${nodeJoin} WHERE ${sql.join([...options.whereClauses], sql` AND `)}`;
|
|
3961
|
+
}
|
|
3962
|
+
function buildWindowedEdgesCte(edgesTable, defaultDirection, edgeKinds, where) {
|
|
3963
|
+
const branches = edgeKinds.flatMap(([kind, window]) => {
|
|
3964
|
+
const direction = window?.direction ?? defaultDirection;
|
|
3965
|
+
const directions = direction === "both" ? ["out", "in"] : [direction];
|
|
3966
|
+
return directions.map((orientedDirection) => {
|
|
3967
|
+
const sourceKind = orientedDirection === "out" ? "from_kind" : "to_kind";
|
|
3968
|
+
const sourceId = orientedDirection === "out" ? "from_id" : "to_id";
|
|
3969
|
+
const targetKind = orientedDirection === "out" ? "to_kind" : "from_kind";
|
|
3970
|
+
const targetId = orientedDirection === "out" ? "to_id" : "from_id";
|
|
3971
|
+
const column = edgeOrderColumnName(window?.orderBy?.field ?? "id");
|
|
3972
|
+
const orderDirection = window?.orderBy?.direction ?? "asc";
|
|
3973
|
+
const omitReverseSelfLoop = direction === "both" && orientedDirection === "in" ? sql` AND NOT (e.from_kind = e.to_kind AND e.from_id = e.to_id)` : sql.empty();
|
|
3974
|
+
const oriented = sql`SELECT e.*, e.${sql.raw(sourceKind)} AS typegraph_source_kind, e.${sql.raw(sourceId)} AS typegraph_source_id, e.${sql.raw(targetKind)} AS typegraph_target_kind, e.${sql.raw(targetId)} AS typegraph_target_id`;
|
|
3975
|
+
if (window === void 0) {
|
|
3976
|
+
return sql`${oriented}, 1 AS typegraphedgerank FROM ${edgesTable} e WHERE ${where} AND e.kind = ${kind}${omitReverseSelfLoop}`;
|
|
3977
|
+
}
|
|
3978
|
+
const rank = sql`ROW_NUMBER() OVER (PARTITION BY e.kind, e.${sql.raw(sourceKind)}, e.${sql.raw(sourceId)} ORDER BY CASE WHEN e.${sql.raw(column)} IS NULL THEN 1 ELSE 0 END ASC, e.${sql.raw(column)} ${sql.raw(orderDirection.toUpperCase())}, e.id ASC)`;
|
|
3979
|
+
const ranked = sql`${oriented}, ${rank} AS typegraphedgerank FROM ${edgesTable} e WHERE ${where} AND e.kind = ${kind}${omitReverseSelfLoop}`;
|
|
3980
|
+
return sql`SELECT * FROM (${ranked}) ranked WHERE ranked.typegraphedgerank <= ${window.limit}`;
|
|
3981
|
+
});
|
|
3982
|
+
});
|
|
3983
|
+
return sql.join(branches, sql` UNION ALL `);
|
|
3597
3984
|
}
|
|
3598
3985
|
|
|
3599
3986
|
// src/store/subgraph.ts
|
|
@@ -3612,52 +3999,53 @@ function normalizeProps(value) {
|
|
|
3612
3999
|
function defineSubgraphProject(_graph) {
|
|
3613
4000
|
return (project) => project;
|
|
3614
4001
|
}
|
|
3615
|
-
|
|
4002
|
+
function buildSubgraphPlan(params, surface) {
|
|
3616
4003
|
const { options } = params;
|
|
3617
4004
|
const { valid: coordinate } = resolveReadCoordinate(
|
|
3618
4005
|
options.temporalMode ?? params.graph.defaults.temporalMode,
|
|
3619
4006
|
options.asOf
|
|
3620
4007
|
);
|
|
3621
|
-
|
|
3622
|
-
const recordedAsOf = options.recordedAsOf;
|
|
4008
|
+
validateEdgeWindows(options.edgeWindows, options.edges);
|
|
3623
4009
|
const baseSchema = params.schema ?? DEFAULT_SQL_SCHEMA;
|
|
3624
|
-
const maxDepth = Math.min(
|
|
3625
|
-
options.maxDepth ?? DEFAULT_SUBGRAPH_MAX_DEPTH,
|
|
3626
|
-
MAX_EXPLICIT_RECURSIVE_DEPTH
|
|
3627
|
-
);
|
|
3628
4010
|
const ctx = {
|
|
3629
4011
|
graphId: params.graphId,
|
|
3630
4012
|
rootId: params.rootId,
|
|
3631
4013
|
edgeKinds: options.edges,
|
|
3632
|
-
maxDepth
|
|
4014
|
+
maxDepth: Math.min(
|
|
4015
|
+
options.maxDepth ?? DEFAULT_SUBGRAPH_MAX_DEPTH,
|
|
4016
|
+
MAX_EXPLICIT_RECURSIVE_DEPTH
|
|
4017
|
+
),
|
|
3633
4018
|
includeKinds: options.includeKinds,
|
|
3634
4019
|
excludeRoot: options.excludeRoot ?? false,
|
|
3635
4020
|
direction: options.direction ?? "out",
|
|
3636
4021
|
cyclePolicy: options.cyclePolicy ?? "prevent",
|
|
3637
|
-
temporalMode,
|
|
4022
|
+
temporalMode: coordinate.mode,
|
|
3638
4023
|
asOf: coordinate.asOf,
|
|
3639
|
-
|
|
4024
|
+
// Recorded coordinates reach here only through the StoreView seam. The
|
|
4025
|
+
// public API rejects them before either execution strategy is selected.
|
|
4026
|
+
recordedAsOf: options.recordedAsOf,
|
|
3640
4027
|
dialect: params.dialect,
|
|
3641
4028
|
schema: recordedReadSchemaFor(
|
|
3642
4029
|
baseSchema,
|
|
3643
|
-
recordedAsOf,
|
|
4030
|
+
options.recordedAsOf,
|
|
3644
4031
|
params.recordedReadBinding,
|
|
3645
|
-
"recorded-subgraph"
|
|
4032
|
+
surface === "subgraph" ? "recorded-subgraph" : "recorded-subgraph-query"
|
|
3646
4033
|
),
|
|
3647
4034
|
recordedReadBinding: params.recordedReadBinding,
|
|
3648
|
-
backend: params.backend
|
|
4035
|
+
backend: params.backend,
|
|
4036
|
+
edgeWindows: options.edgeWindows
|
|
3649
4037
|
};
|
|
3650
|
-
const
|
|
4038
|
+
const introspector = getSubgraphSchemaIntrospector(params.graph);
|
|
3651
4039
|
const nodeProjectionPlan = buildProjectionPlan(
|
|
3652
4040
|
getIncludedNodeKinds(params.graph, options.includeKinds),
|
|
3653
4041
|
options.project?.nodes,
|
|
3654
|
-
(kind, field2) =>
|
|
4042
|
+
(kind, field2) => introspector.getFieldTypeInfo(kind, field2),
|
|
3655
4043
|
"node"
|
|
3656
4044
|
);
|
|
3657
4045
|
const edgeProjectionPlan = buildProjectionPlan(
|
|
3658
4046
|
dedupeStrings(options.edges),
|
|
3659
4047
|
options.project?.edges,
|
|
3660
|
-
(kind, field2) =>
|
|
4048
|
+
(kind, field2) => introspector.getEdgeFieldTypeInfo(kind, field2),
|
|
3661
4049
|
"edge"
|
|
3662
4050
|
);
|
|
3663
4051
|
const reachableCte = buildReachableCte({
|
|
@@ -3672,13 +4060,29 @@ async function executeSubgraph(params) {
|
|
|
3672
4060
|
...ctx.asOf !== void 0 && { asOf: ctx.asOf },
|
|
3673
4061
|
...ctx.recordedAsOf !== void 0 && { recordedAsOf: ctx.recordedAsOf },
|
|
3674
4062
|
dialect: ctx.dialect,
|
|
3675
|
-
//
|
|
4063
|
+
// The recursive compiler derives the recorded relation from the pin.
|
|
3676
4064
|
schema: baseSchema,
|
|
3677
4065
|
...ctx.recordedReadBinding === void 0 ? {} : { recordedReadBinding: ctx.recordedReadBinding },
|
|
3678
4066
|
recursiveTraversal: resolveRecursiveTraversal(params.backend.capabilities),
|
|
3679
|
-
operation:
|
|
4067
|
+
operation: surface,
|
|
4068
|
+
...ctx.edgeWindows === void 0 ? {} : { edgeWindows: ctx.edgeWindows }
|
|
3680
4069
|
});
|
|
3681
|
-
|
|
4070
|
+
return {
|
|
4071
|
+
ctx,
|
|
4072
|
+
reachableCte,
|
|
4073
|
+
includedIdsCte: buildIncludedIdsCte(ctx),
|
|
4074
|
+
nodeProjectionPlan,
|
|
4075
|
+
edgeProjectionPlan
|
|
4076
|
+
};
|
|
4077
|
+
}
|
|
4078
|
+
async function executeSubgraph(params) {
|
|
4079
|
+
const {
|
|
4080
|
+
ctx,
|
|
4081
|
+
reachableCte,
|
|
4082
|
+
includedIdsCte,
|
|
4083
|
+
nodeProjectionPlan,
|
|
4084
|
+
edgeProjectionPlan
|
|
4085
|
+
} = buildSubgraphPlan(params, "subgraph");
|
|
3682
4086
|
let membership;
|
|
3683
4087
|
const membershipStrategy = ctx.dialect.capabilities.subgraphMembershipStrategy;
|
|
3684
4088
|
switch (membershipStrategy) {
|
|
@@ -3717,24 +4121,47 @@ async function executeSubgraph(params) {
|
|
|
3717
4121
|
fetchSubgraphNodes(ctx, membership, nodeProjectionPlan),
|
|
3718
4122
|
fetchSubgraphEdges(ctx, membership, edgeProjectionPlan)
|
|
3719
4123
|
]);
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
4124
|
+
return assembleSubgraphResult(
|
|
4125
|
+
ctx.rootId,
|
|
4126
|
+
nodeRows.map((row) => mapSubgraphNodeRow(row, nodeProjectionPlan)),
|
|
4127
|
+
edgeRows.map((row) => mapSubgraphEdgeRow(row, edgeProjectionPlan))
|
|
4128
|
+
);
|
|
4129
|
+
}
|
|
4130
|
+
function createSubgraphRead(params) {
|
|
4131
|
+
const {
|
|
4132
|
+
ctx,
|
|
4133
|
+
reachableCte,
|
|
4134
|
+
includedIdsCte,
|
|
4135
|
+
nodeProjectionPlan: nodePlan,
|
|
4136
|
+
edgeProjectionPlan: edgePlan
|
|
4137
|
+
} = buildSubgraphPlan(params, "batchOnce.subgraph");
|
|
4138
|
+
const query = buildOneStatementSubgraphQuery(
|
|
4139
|
+
ctx,
|
|
4140
|
+
reachableCte,
|
|
4141
|
+
includedIdsCte,
|
|
4142
|
+
nodePlan,
|
|
4143
|
+
edgePlan
|
|
4144
|
+
);
|
|
4145
|
+
function mapRows(rows) {
|
|
4146
|
+
return mapOneStatementSubgraphRows(
|
|
4147
|
+
ctx.rootId,
|
|
4148
|
+
rows,
|
|
4149
|
+
nodePlan,
|
|
4150
|
+
edgePlan
|
|
4151
|
+
);
|
|
3731
4152
|
}
|
|
3732
|
-
const root = nodesMap.get(ctx.rootId);
|
|
3733
4153
|
return {
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
4154
|
+
execute: async () => mapRows(
|
|
4155
|
+
await params.backend.execute(
|
|
4156
|
+
asCompiledRowsSql(query)
|
|
4157
|
+
)
|
|
4158
|
+
),
|
|
4159
|
+
compileOneStatementBatchItem: () => ({
|
|
4160
|
+
query: asCompiledRowsSql(query),
|
|
4161
|
+
outputNames: oneStatementSubgraphOutputNames(nodePlan, edgePlan),
|
|
4162
|
+
orderBy: [],
|
|
4163
|
+
mapRows
|
|
4164
|
+
})
|
|
3738
4165
|
};
|
|
3739
4166
|
}
|
|
3740
4167
|
var introspectorCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -3815,6 +4242,38 @@ function buildIncludedIdsCte(ctx) {
|
|
|
3815
4242
|
const whereClause = filters.length > 0 ? sql` WHERE ${sql.join(filters, sql` AND `)}` : sql``;
|
|
3816
4243
|
return sql`, included_ids AS (SELECT DISTINCT id FROM reachable${whereClause})`;
|
|
3817
4244
|
}
|
|
4245
|
+
function buildSubgraphEdgeSource(ctx, edgeTemporalFilter) {
|
|
4246
|
+
const windows = Object.entries(ctx.edgeWindows ?? {}).filter(
|
|
4247
|
+
(entry2) => entry2[1] !== void 0
|
|
4248
|
+
);
|
|
4249
|
+
if (windows.length === 0) return ctx.schema.edgesTable;
|
|
4250
|
+
const edgeKindFilter = compileKindFilter(sql.raw("e.kind"), ctx.edgeKinds);
|
|
4251
|
+
const windowedEdges = buildWindowedEdgesCte(
|
|
4252
|
+
ctx.schema.edgesTable,
|
|
4253
|
+
ctx.direction,
|
|
4254
|
+
ctx.edgeKinds.map((kind) => [kind, ctx.edgeWindows?.[kind]]),
|
|
4255
|
+
sql.join(
|
|
4256
|
+
[sql`e.graph_id = ${ctx.graphId}`, edgeKindFilter, edgeTemporalFilter],
|
|
4257
|
+
sql` AND `
|
|
4258
|
+
)
|
|
4259
|
+
);
|
|
4260
|
+
const physicalColumns = [
|
|
4261
|
+
"graph_id",
|
|
4262
|
+
"id",
|
|
4263
|
+
"kind",
|
|
4264
|
+
"from_kind",
|
|
4265
|
+
"from_id",
|
|
4266
|
+
"to_kind",
|
|
4267
|
+
"to_id",
|
|
4268
|
+
"props",
|
|
4269
|
+
"valid_from",
|
|
4270
|
+
"valid_to",
|
|
4271
|
+
"created_at",
|
|
4272
|
+
"updated_at",
|
|
4273
|
+
"deleted_at"
|
|
4274
|
+
].map((column) => sql.raw(`windowed_edge.${column}`));
|
|
4275
|
+
return sql`(SELECT DISTINCT ${sql.join(physicalColumns, sql`, `)} FROM (${windowedEdges}) windowed_edge)`;
|
|
4276
|
+
}
|
|
3818
4277
|
function textArrayParam(values) {
|
|
3819
4278
|
const elements = values.map(
|
|
3820
4279
|
(value) => `"${value.replaceAll("\\", "\\\\").replaceAll('"', String.raw`\"`)}"`
|
|
@@ -3829,6 +4288,125 @@ async function fetchIncludedIds(ctx, reachableCte, includedIdsCte) {
|
|
|
3829
4288
|
);
|
|
3830
4289
|
return rows.map((row) => row.id);
|
|
3831
4290
|
}
|
|
4291
|
+
function projectionOutputNames(plan) {
|
|
4292
|
+
return [...plan.projectedKinds.values()].flatMap(
|
|
4293
|
+
(kindPlan) => kindPlan.propertyFields.map((field2) => field2.outputName)
|
|
4294
|
+
);
|
|
4295
|
+
}
|
|
4296
|
+
function oneStatementSubgraphOutputNames(nodePlan, edgePlan) {
|
|
4297
|
+
return [
|
|
4298
|
+
"typegraph_entity",
|
|
4299
|
+
"id",
|
|
4300
|
+
"kind",
|
|
4301
|
+
"from_kind",
|
|
4302
|
+
"from_id",
|
|
4303
|
+
"to_kind",
|
|
4304
|
+
"to_id",
|
|
4305
|
+
"props",
|
|
4306
|
+
"version",
|
|
4307
|
+
"valid_from",
|
|
4308
|
+
"valid_to",
|
|
4309
|
+
"created_at",
|
|
4310
|
+
"updated_at",
|
|
4311
|
+
"deleted_at",
|
|
4312
|
+
...projectionOutputNames(nodePlan),
|
|
4313
|
+
...projectionOutputNames(edgePlan)
|
|
4314
|
+
];
|
|
4315
|
+
}
|
|
4316
|
+
function nullProjectionColumns(plan) {
|
|
4317
|
+
return projectionOutputNames(plan).map(
|
|
4318
|
+
(outputName) => sql`NULL AS ${quoteIdentifier(outputName)}`
|
|
4319
|
+
);
|
|
4320
|
+
}
|
|
4321
|
+
function buildOneStatementSubgraphQuery(ctx, reachable, includedIds, nodePlan, edgePlan) {
|
|
4322
|
+
const instant = currentReadInstant();
|
|
4323
|
+
const nodeTemporal = compileTemporalFilter({
|
|
4324
|
+
mode: ctx.temporalMode,
|
|
4325
|
+
asOf: ctx.asOf,
|
|
4326
|
+
recordedAsOf: ctx.recordedAsOf,
|
|
4327
|
+
tableAlias: "n",
|
|
4328
|
+
currentTimestamp: instant,
|
|
4329
|
+
recordedReadBinding: ctx.recordedReadBinding
|
|
4330
|
+
});
|
|
4331
|
+
const edgeTemporal = compileTemporalFilter({
|
|
4332
|
+
mode: ctx.temporalMode,
|
|
4333
|
+
asOf: ctx.asOf,
|
|
4334
|
+
recordedAsOf: ctx.recordedAsOf,
|
|
4335
|
+
tableAlias: "e",
|
|
4336
|
+
currentTimestamp: instant,
|
|
4337
|
+
recordedReadBinding: ctx.recordedReadBinding
|
|
4338
|
+
});
|
|
4339
|
+
const nodeColumns = [
|
|
4340
|
+
sql`'node' AS typegraph_entity`,
|
|
4341
|
+
sql`n.id`,
|
|
4342
|
+
sql`n.kind`,
|
|
4343
|
+
sql`NULL AS from_kind`,
|
|
4344
|
+
sql`NULL AS from_id`,
|
|
4345
|
+
sql`NULL AS to_kind`,
|
|
4346
|
+
sql`NULL AS to_id`,
|
|
4347
|
+
buildFullPropsColumn("n", nodePlan),
|
|
4348
|
+
...buildMetadataColumns("n", nodePlan, [
|
|
4349
|
+
"version",
|
|
4350
|
+
"valid_from",
|
|
4351
|
+
"valid_to",
|
|
4352
|
+
"created_at",
|
|
4353
|
+
"updated_at",
|
|
4354
|
+
"deleted_at"
|
|
4355
|
+
]),
|
|
4356
|
+
...buildProjectedPropertyColumns("n", nodePlan, ctx.dialect),
|
|
4357
|
+
...nullProjectionColumns(edgePlan)
|
|
4358
|
+
];
|
|
4359
|
+
const edgeColumns = [
|
|
4360
|
+
sql`'edge' AS typegraph_entity`,
|
|
4361
|
+
sql`e.id`,
|
|
4362
|
+
sql`e.kind`,
|
|
4363
|
+
sql`e.from_kind`,
|
|
4364
|
+
sql`e.from_id`,
|
|
4365
|
+
sql`e.to_kind`,
|
|
4366
|
+
sql`e.to_id`,
|
|
4367
|
+
buildFullPropsColumn("e", edgePlan),
|
|
4368
|
+
sql`NULL AS version`,
|
|
4369
|
+
...buildMetadataColumns("e", edgePlan, [
|
|
4370
|
+
"valid_from",
|
|
4371
|
+
"valid_to",
|
|
4372
|
+
"created_at",
|
|
4373
|
+
"updated_at",
|
|
4374
|
+
"deleted_at"
|
|
4375
|
+
]),
|
|
4376
|
+
...nullProjectionColumns(nodePlan),
|
|
4377
|
+
...buildProjectedPropertyColumns("e", edgePlan, ctx.dialect)
|
|
4378
|
+
];
|
|
4379
|
+
const edgeSource = buildSubgraphEdgeSource(ctx, edgeTemporal);
|
|
4380
|
+
return sql`${reachable}${includedIds} SELECT ${sql.join(nodeColumns, sql`, `)} FROM ${ctx.schema.nodesTable} n WHERE n.graph_id = ${ctx.graphId} AND ${nodeTemporal} AND n.id IN (SELECT id FROM included_ids) UNION ALL SELECT ${sql.join(edgeColumns, sql`, `)} FROM ${edgeSource} e WHERE e.graph_id = ${ctx.graphId} AND ${compileKindFilter(sql.raw("e.kind"), ctx.edgeKinds)} AND ${edgeTemporal} AND e.from_id IN (SELECT id FROM included_ids) AND e.to_id IN (SELECT id FROM included_ids)`;
|
|
4381
|
+
}
|
|
4382
|
+
function mapOneStatementSubgraphRows(rootId, rows, nodePlan, edgePlan) {
|
|
4383
|
+
const nodes = [];
|
|
4384
|
+
const edges = [];
|
|
4385
|
+
for (const row of rows) {
|
|
4386
|
+
if (row.typegraph_entity === "node") {
|
|
4387
|
+
nodes.push(mapSubgraphNodeRow(row, nodePlan));
|
|
4388
|
+
continue;
|
|
4389
|
+
}
|
|
4390
|
+
edges.push(mapSubgraphEdgeRow(row, edgePlan));
|
|
4391
|
+
}
|
|
4392
|
+
return assembleSubgraphResult(rootId, nodes, edges);
|
|
4393
|
+
}
|
|
4394
|
+
function assembleSubgraphResult(rootId, nodeValues, edgeValues) {
|
|
4395
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
4396
|
+
for (const node of nodeValues) nodes.set(node.id, node);
|
|
4397
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
4398
|
+
const reverseAdjacency = /* @__PURE__ */ new Map();
|
|
4399
|
+
for (const edge of edgeValues) {
|
|
4400
|
+
insertAdjacencyEntry(adjacency, edge.fromId, edge.kind, edge);
|
|
4401
|
+
insertAdjacencyEntry(reverseAdjacency, edge.toId, edge.kind, edge);
|
|
4402
|
+
}
|
|
4403
|
+
return {
|
|
4404
|
+
root: nodes.get(rootId),
|
|
4405
|
+
nodes,
|
|
4406
|
+
adjacency,
|
|
4407
|
+
reverseAdjacency
|
|
4408
|
+
};
|
|
4409
|
+
}
|
|
3832
4410
|
async function fetchSubgraphNodes(ctx, membership, projectionPlan) {
|
|
3833
4411
|
const nodeTemporalFilter = compileTemporalFilter({
|
|
3834
4412
|
mode: ctx.temporalMode,
|
|
@@ -3885,12 +4463,33 @@ async function fetchSubgraphEdges(ctx, membership, projectionPlan) {
|
|
|
3885
4463
|
]),
|
|
3886
4464
|
...buildProjectedPropertyColumns("e", projectionPlan, ctx.dialect)
|
|
3887
4465
|
];
|
|
3888
|
-
const
|
|
4466
|
+
const edgesSource = buildSubgraphEdgeSource(ctx, edgeTemporalFilter);
|
|
4467
|
+
const query = sql`${membership.prefix}SELECT ${sql.join(columns, sql`, `)} FROM ${edgesSource} e WHERE e.graph_id = ${ctx.graphId} AND ${edgeKindFilter} AND ${edgeTemporalFilter} AND ${membership.idFilter(sql.raw("e.from_id"))} AND ${membership.idFilter(sql.raw("e.to_id"))}`;
|
|
3889
4468
|
if (membership.parameterDependentPlan) markForceCustomPlan(query);
|
|
3890
4469
|
return ctx.backend.execute(
|
|
3891
4470
|
asCompiledRowsSql(query)
|
|
3892
4471
|
);
|
|
3893
4472
|
}
|
|
4473
|
+
function validateEdgeWindows(windows, selectedEdgeKinds) {
|
|
4474
|
+
for (const [kind, window] of Object.entries(windows ?? {})) {
|
|
4475
|
+
if (!selectedEdgeKinds.includes(kind)) {
|
|
4476
|
+
throw new ValidationError(
|
|
4477
|
+
"Subgraph edge windows must name a traversed edge kind",
|
|
4478
|
+
{
|
|
4479
|
+
issues: [
|
|
4480
|
+
{
|
|
4481
|
+
path: `edgeWindows.${kind}`,
|
|
4482
|
+
message: "Edge kind is not present in options.edges"
|
|
4483
|
+
}
|
|
4484
|
+
]
|
|
4485
|
+
}
|
|
4486
|
+
);
|
|
4487
|
+
}
|
|
4488
|
+
if (window !== void 0) {
|
|
4489
|
+
validateEdgeReadBounds(window, `edgeWindows.${kind}`);
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
3894
4493
|
function buildMetadataColumns(alias, plan, columns) {
|
|
3895
4494
|
if (plan.projectedKinds.size === 0) {
|
|
3896
4495
|
return columns.map((col) => sql`${sql.raw(`${alias}.${col}`)}`);
|
|
@@ -3958,12 +4557,23 @@ function applyProjectedFields(target, row, kindPlan) {
|
|
|
3958
4557
|
);
|
|
3959
4558
|
}
|
|
3960
4559
|
}
|
|
4560
|
+
function normalizeSubgraphRowTimestamps(row) {
|
|
4561
|
+
return {
|
|
4562
|
+
...row,
|
|
4563
|
+
valid_from: normalizeRowTimestamp(row.valid_from, "valid_from"),
|
|
4564
|
+
valid_to: normalizeRowTimestamp(row.valid_to, "valid_to"),
|
|
4565
|
+
created_at: normalizeRequiredRowTimestamp(row.created_at, "created_at"),
|
|
4566
|
+
updated_at: normalizeRequiredRowTimestamp(row.updated_at, "updated_at"),
|
|
4567
|
+
deleted_at: normalizeRowTimestamp(row.deleted_at, "deleted_at")
|
|
4568
|
+
};
|
|
4569
|
+
}
|
|
3961
4570
|
function mapSubgraphNodeRow(row, projectionPlan) {
|
|
3962
4571
|
const kindPlan = projectionPlan.projectedKinds.get(row.kind);
|
|
3963
4572
|
if (kindPlan === void 0) {
|
|
4573
|
+
const normalizedRow = normalizeSubgraphRowTimestamps(row);
|
|
3964
4574
|
return rowToNode({
|
|
3965
|
-
...
|
|
3966
|
-
props: normalizeProps(
|
|
4575
|
+
...normalizedRow,
|
|
4576
|
+
props: normalizeProps(normalizedRow.props)
|
|
3967
4577
|
});
|
|
3968
4578
|
}
|
|
3969
4579
|
const projectedNode = {
|
|
@@ -3971,7 +4581,7 @@ function mapSubgraphNodeRow(row, projectionPlan) {
|
|
|
3971
4581
|
id: row.id
|
|
3972
4582
|
};
|
|
3973
4583
|
if (kindPlan.includeMeta) {
|
|
3974
|
-
projectedNode["meta"] = rowToNodeMeta(row);
|
|
4584
|
+
projectedNode["meta"] = rowToNodeMeta(normalizeSubgraphRowTimestamps(row));
|
|
3975
4585
|
}
|
|
3976
4586
|
applyProjectedFields(projectedNode, row, kindPlan);
|
|
3977
4587
|
return projectedNode;
|
|
@@ -3979,9 +4589,10 @@ function mapSubgraphNodeRow(row, projectionPlan) {
|
|
|
3979
4589
|
function mapSubgraphEdgeRow(row, projectionPlan) {
|
|
3980
4590
|
const kindPlan = projectionPlan.projectedKinds.get(row.kind);
|
|
3981
4591
|
if (kindPlan === void 0) {
|
|
4592
|
+
const normalizedRow = normalizeSubgraphRowTimestamps(row);
|
|
3982
4593
|
return rowToEdge({
|
|
3983
|
-
...
|
|
3984
|
-
props: normalizeProps(
|
|
4594
|
+
...normalizedRow,
|
|
4595
|
+
props: normalizeProps(normalizedRow.props)
|
|
3985
4596
|
});
|
|
3986
4597
|
}
|
|
3987
4598
|
const projectedEdge = {
|
|
@@ -3993,7 +4604,7 @@ function mapSubgraphEdgeRow(row, projectionPlan) {
|
|
|
3993
4604
|
toId: row.to_id
|
|
3994
4605
|
};
|
|
3995
4606
|
if (kindPlan.includeMeta) {
|
|
3996
|
-
projectedEdge["meta"] = rowToEdgeMeta(row);
|
|
4607
|
+
projectedEdge["meta"] = rowToEdgeMeta(normalizeSubgraphRowTimestamps(row));
|
|
3997
4608
|
}
|
|
3998
4609
|
applyProjectedFields(projectedEdge, row, kindPlan);
|
|
3999
4610
|
return projectedEdge;
|
|
@@ -7164,7 +7775,7 @@ function buildQueryAst(config, state) {
|
|
|
7164
7775
|
// src/query/builder/internal-context.ts
|
|
7165
7776
|
var contexts = /* @__PURE__ */ new WeakMap();
|
|
7166
7777
|
function registerQueryBuilderInternalContext(config, context) {
|
|
7167
|
-
if (context.recordedReadBinding === void 0 && context.sealedCoordinate === void 0 && context.runtimeKindTokenResolver === void 0) {
|
|
7778
|
+
if (context.recordedReadBinding === void 0 && context.sealedCoordinate === void 0 && context.runtimeKindTokenResolver === void 0 && context.expectedSchemaVersion === void 0) {
|
|
7168
7779
|
return;
|
|
7169
7780
|
}
|
|
7170
7781
|
contexts.set(config, context);
|
|
@@ -7222,6 +7833,97 @@ function buildVectorSlots(registry) {
|
|
|
7222
7833
|
return slots;
|
|
7223
7834
|
}
|
|
7224
7835
|
|
|
7836
|
+
// src/query/builder/one-statement-batch.ts
|
|
7837
|
+
var ORDER_COLUMN = "typegraphbatchordinal";
|
|
7838
|
+
var ORDER_KEY_PREFIX = "typegraphbatchorder";
|
|
7839
|
+
function oneStatementBatchOrderColumn(index) {
|
|
7840
|
+
return `${ORDER_KEY_PREFIX}${index}`;
|
|
7841
|
+
}
|
|
7842
|
+
function buildOrdinalOrder(rowAlias, orderBy) {
|
|
7843
|
+
if (orderBy.length === 0) return sql.empty();
|
|
7844
|
+
const row = sql.identifier(rowAlias);
|
|
7845
|
+
const terms = orderBy.flatMap((order) => {
|
|
7846
|
+
const column = sql`${row}.${sql.identifier(order.column)}`;
|
|
7847
|
+
const nullDirection = order.nulls === "first" ? sql.raw("DESC") : sql.raw("ASC");
|
|
7848
|
+
return [
|
|
7849
|
+
sql`(${column} IS NULL) ${nullDirection}`,
|
|
7850
|
+
sql`${column} ${sql.raw(order.direction.toUpperCase())}`
|
|
7851
|
+
];
|
|
7852
|
+
});
|
|
7853
|
+
return sql`ORDER BY ${sql.join(terms, sql`, `)}`;
|
|
7854
|
+
}
|
|
7855
|
+
async function executeOneStatementBatch(backend, queries) {
|
|
7856
|
+
const dialect = getDialect(backend.dialect);
|
|
7857
|
+
const items = queries.map((query) => {
|
|
7858
|
+
const compile = query.compileOneStatementBatchItem;
|
|
7859
|
+
if (compile === void 0) {
|
|
7860
|
+
throw new ConfigurationError(
|
|
7861
|
+
"Read cannot be embedded in store.batchOnce().",
|
|
7862
|
+
{ operation: "batchOnce" },
|
|
7863
|
+
{
|
|
7864
|
+
suggestion: "Pass a fluent relational query or a set-oriented read returned by the store's query helpers."
|
|
7865
|
+
}
|
|
7866
|
+
);
|
|
7867
|
+
}
|
|
7868
|
+
return compile.call(query);
|
|
7869
|
+
});
|
|
7870
|
+
const ctes = [];
|
|
7871
|
+
const branches = [];
|
|
7872
|
+
for (const [index, item] of items.entries()) {
|
|
7873
|
+
const reservedAlias = item.outputNames.find(
|
|
7874
|
+
(outputName) => outputName === ORDER_COLUMN || outputName.startsWith(ORDER_KEY_PREFIX)
|
|
7875
|
+
);
|
|
7876
|
+
if (reservedAlias !== void 0) {
|
|
7877
|
+
throw new ConfigurationError(
|
|
7878
|
+
`Query output alias "${reservedAlias}" is reserved by store.batchOnce().`,
|
|
7879
|
+
{ operation: "batchOnce", alias: reservedAlias }
|
|
7880
|
+
);
|
|
7881
|
+
}
|
|
7882
|
+
const sourceName = `typegraph_batch_source_${index}`;
|
|
7883
|
+
const rowsName = `typegraph_batch_rows_${index}`;
|
|
7884
|
+
const ordinalOrder = buildOrdinalOrder(sourceName, item.orderBy);
|
|
7885
|
+
ctes.push(
|
|
7886
|
+
sql`${sql.identifier(sourceName)} AS (${item.query})`,
|
|
7887
|
+
sql`${sql.identifier(rowsName)} AS (SELECT ${sql.identifier(sourceName)}.*, ROW_NUMBER() OVER (${ordinalOrder}) AS ${sql.identifier(ORDER_COLUMN)} FROM ${sql.identifier(sourceName)})`
|
|
7888
|
+
);
|
|
7889
|
+
const payload = dialect.orderedRowsJsonArray(
|
|
7890
|
+
rowsName,
|
|
7891
|
+
item.outputNames,
|
|
7892
|
+
ORDER_COLUMN
|
|
7893
|
+
);
|
|
7894
|
+
branches.push(sql`SELECT ${index} AS batch_index, ${payload} AS payload`);
|
|
7895
|
+
}
|
|
7896
|
+
const statement = asCompiledRowsSql(
|
|
7897
|
+
sql`WITH ${sql.join(ctes, sql`, `)} SELECT * FROM (${sql.join(branches, sql` UNION ALL `)}) AS typegraph_batch_envelope ORDER BY batch_index`
|
|
7898
|
+
);
|
|
7899
|
+
const envelopes = await backend.execute(statement);
|
|
7900
|
+
const payloads = /* @__PURE__ */ new Map();
|
|
7901
|
+
for (const envelope of envelopes) {
|
|
7902
|
+
payloads.set(Number(envelope.batch_index), parsePayload(envelope.payload));
|
|
7903
|
+
}
|
|
7904
|
+
return items.map(
|
|
7905
|
+
(item, index) => item.mapRows(payloads.get(index) ?? [])
|
|
7906
|
+
);
|
|
7907
|
+
}
|
|
7908
|
+
function parsePayload(value) {
|
|
7909
|
+
const parsed = typeof value === "string" ? JSON.parse(value) : value;
|
|
7910
|
+
if (!Array.isArray(parsed)) {
|
|
7911
|
+
throw new ConfigurationError(
|
|
7912
|
+
"One-statement batch returned a non-array JSON payload.",
|
|
7913
|
+
{ operation: "batchOnce" }
|
|
7914
|
+
);
|
|
7915
|
+
}
|
|
7916
|
+
return parsed.map((row) => {
|
|
7917
|
+
if (typeof row !== "object" || row === null || Array.isArray(row)) {
|
|
7918
|
+
throw new ConfigurationError(
|
|
7919
|
+
"One-statement batch returned a non-object row.",
|
|
7920
|
+
{ operation: "batchOnce" }
|
|
7921
|
+
);
|
|
7922
|
+
}
|
|
7923
|
+
return row;
|
|
7924
|
+
});
|
|
7925
|
+
}
|
|
7926
|
+
|
|
7225
7927
|
// src/query/builder/order-by-field.ts
|
|
7226
7928
|
var COMMON_SYSTEM_ORDER_FIELDS = /* @__PURE__ */ new Map([
|
|
7227
7929
|
["id", "string"],
|
|
@@ -7511,6 +8213,12 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7511
8213
|
* @throws Error if no backend is configured
|
|
7512
8214
|
*/
|
|
7513
8215
|
prepare() {
|
|
8216
|
+
if (getQueryBuilderInternalContext(this.#config).expectedSchemaVersion !== void 0) {
|
|
8217
|
+
throw new ConfigurationError(
|
|
8218
|
+
"Prepared queries are unavailable inside withCheckedReads().",
|
|
8219
|
+
{ operation: "withCheckedReads.prepare" }
|
|
8220
|
+
);
|
|
8221
|
+
}
|
|
7514
8222
|
if (!this.#config.backend) {
|
|
7515
8223
|
throw new Error(
|
|
7516
8224
|
"Cannot prepare query: no backend configured. Use store.query() or pass a backend to createQueryBuilder()."
|
|
@@ -7631,6 +8339,10 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7631
8339
|
"Query contains param() references. Use .prepare().execute({...}) instead of .execute()."
|
|
7632
8340
|
);
|
|
7633
8341
|
}
|
|
8342
|
+
const checked = getQueryBuilderInternalContext(
|
|
8343
|
+
this.#config
|
|
8344
|
+
).expectedSchemaVersion;
|
|
8345
|
+
if (checked !== void 0) return this.executeChecked(checked.value);
|
|
7634
8346
|
const optimizedResult = await this.#tryOptimizedExecution();
|
|
7635
8347
|
if (optimizedResult !== void 0) {
|
|
7636
8348
|
return optimizedResult;
|
|
@@ -7696,6 +8408,24 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7696
8408
|
"Query contains param() references. Use .prepare().execute({...}) instead of .execute()."
|
|
7697
8409
|
);
|
|
7698
8410
|
}
|
|
8411
|
+
const checked = getQueryBuilderInternalContext(
|
|
8412
|
+
this.#config
|
|
8413
|
+
).expectedSchemaVersion;
|
|
8414
|
+
if (checked !== void 0) {
|
|
8415
|
+
const rows2 = await executeSchemaCheckedRead({
|
|
8416
|
+
backend,
|
|
8417
|
+
ast,
|
|
8418
|
+
graphId: this.#config.graphId,
|
|
8419
|
+
expectedVersion: checked.value,
|
|
8420
|
+
compile: () => compileQuery(ast, this.#config.graphId, this.#compileOptions())
|
|
8421
|
+
});
|
|
8422
|
+
return mapResults(
|
|
8423
|
+
rows2,
|
|
8424
|
+
this.#state.startAlias,
|
|
8425
|
+
this.#state.traversals,
|
|
8426
|
+
this.#selectFn
|
|
8427
|
+
);
|
|
8428
|
+
}
|
|
7699
8429
|
const optimizedResult = await this.#tryOptimizedExecutionOn(backend);
|
|
7700
8430
|
if (optimizedResult !== void 0) {
|
|
7701
8431
|
return optimizedResult;
|
|
@@ -7713,6 +8443,53 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
7713
8443
|
this.#selectFn
|
|
7714
8444
|
);
|
|
7715
8445
|
}
|
|
8446
|
+
/** @internal Embedding contract consumed by `store.batchOnce()`. */
|
|
8447
|
+
compileOneStatementBatchItem() {
|
|
8448
|
+
if (getQueryBuilderInternalContext(this.#config).expectedSchemaVersion !== void 0) {
|
|
8449
|
+
throw new ConfigurationError(
|
|
8450
|
+
"Queries from withCheckedReads() cannot be embedded in batchOnce().",
|
|
8451
|
+
{ operation: "withCheckedReads.batchOnce" }
|
|
8452
|
+
);
|
|
8453
|
+
}
|
|
8454
|
+
if (this.#hasParameterReferences()) {
|
|
8455
|
+
throw new Error(
|
|
8456
|
+
"Query contains param() references. Bind prepared queries before batching."
|
|
8457
|
+
);
|
|
8458
|
+
}
|
|
8459
|
+
const ast = this.toAst();
|
|
8460
|
+
const batchOrderBy = (ast.orderBy ?? []).map((order, index) => ({
|
|
8461
|
+
column: oneStatementBatchOrderColumn(index),
|
|
8462
|
+
direction: order.direction,
|
|
8463
|
+
nulls: order.nulls ?? (order.direction === "asc" ? "last" : "first")
|
|
8464
|
+
}));
|
|
8465
|
+
const batchAst = batchOrderBy.length === 0 ? ast : {
|
|
8466
|
+
...ast,
|
|
8467
|
+
projection: {
|
|
8468
|
+
fields: [
|
|
8469
|
+
...ast.projection.fields,
|
|
8470
|
+
...(ast.orderBy ?? []).map((order, index) => ({
|
|
8471
|
+
outputName: oneStatementBatchOrderColumn(index),
|
|
8472
|
+
source: order.field
|
|
8473
|
+
}))
|
|
8474
|
+
]
|
|
8475
|
+
}
|
|
8476
|
+
};
|
|
8477
|
+
return {
|
|
8478
|
+
query: compileQuery(
|
|
8479
|
+
batchAst,
|
|
8480
|
+
this.#config.graphId,
|
|
8481
|
+
this.#compileOptions()
|
|
8482
|
+
),
|
|
8483
|
+
outputNames: ast.projection.fields.map((field2) => field2.outputName),
|
|
8484
|
+
orderBy: batchOrderBy,
|
|
8485
|
+
mapRows: (rows) => mapResults(
|
|
8486
|
+
transformPathColumns(rows, this.#state, this.#dialect()),
|
|
8487
|
+
this.#state.startAlias,
|
|
8488
|
+
this.#state.traversals,
|
|
8489
|
+
this.#selectFn
|
|
8490
|
+
)
|
|
8491
|
+
};
|
|
8492
|
+
}
|
|
7716
8493
|
/**
|
|
7717
8494
|
* Attempts optimized execution by tracking which fields the select callback accesses.
|
|
7718
8495
|
*
|
|
@@ -8135,6 +8912,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
8135
8912
|
* @throws ValidationError if cursor columns don't match query ORDER BY columns
|
|
8136
8913
|
*/
|
|
8137
8914
|
async paginate(options) {
|
|
8915
|
+
this.#refuseCheckedReadSurface("paginate");
|
|
8138
8916
|
if (!this.#config.backend) {
|
|
8139
8917
|
throw new Error(
|
|
8140
8918
|
"Cannot execute query: no backend configured. Use store.query() or pass a backend to createQueryBuilder()."
|
|
@@ -8216,6 +8994,7 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
8216
8994
|
* @throws ValidationError if ORDER BY is not specified
|
|
8217
8995
|
*/
|
|
8218
8996
|
stream(options) {
|
|
8997
|
+
this.#refuseCheckedReadSurface("stream");
|
|
8219
8998
|
if (this.#state.orderBy.length === 0) {
|
|
8220
8999
|
throw new ValidationError(
|
|
8221
9000
|
"Streaming requires ORDER BY. Add .orderBy() before .stream()",
|
|
@@ -8235,6 +9014,15 @@ var ExecutableQuery = class _ExecutableQuery {
|
|
|
8235
9014
|
(paginateOptions) => this.paginate(paginateOptions)
|
|
8236
9015
|
);
|
|
8237
9016
|
}
|
|
9017
|
+
#refuseCheckedReadSurface(surface) {
|
|
9018
|
+
if (getQueryBuilderInternalContext(this.#config).expectedSchemaVersion === void 0) {
|
|
9019
|
+
return;
|
|
9020
|
+
}
|
|
9021
|
+
throw new ConfigurationError(
|
|
9022
|
+
`${surface === "paginate" ? "Pagination" : "Streaming"} is unavailable inside withCheckedReads().`,
|
|
9023
|
+
{ operation: `withCheckedReads.${surface}` }
|
|
9024
|
+
);
|
|
9025
|
+
}
|
|
8238
9026
|
/**
|
|
8239
9027
|
* Executes a query with cursor conditions applied.
|
|
8240
9028
|
*/
|
|
@@ -8401,6 +9189,12 @@ var ExecutableAggregateQuery = class _ExecutableAggregateQuery {
|
|
|
8401
9189
|
* @throws Error if no backend is configured
|
|
8402
9190
|
*/
|
|
8403
9191
|
async execute() {
|
|
9192
|
+
if (getQueryBuilderInternalContext(this.#config).expectedSchemaVersion !== void 0) {
|
|
9193
|
+
throw new ConfigurationError(
|
|
9194
|
+
"Aggregate queries are unavailable inside withCheckedReads().",
|
|
9195
|
+
{ operation: "withCheckedReads.aggregate" }
|
|
9196
|
+
);
|
|
9197
|
+
}
|
|
8404
9198
|
const backend = this.#config.backend;
|
|
8405
9199
|
if (!backend) {
|
|
8406
9200
|
throw new Error(
|
|
@@ -9928,6 +10722,7 @@ var UnionableQuery = class _UnionableQuery {
|
|
|
9928
10722
|
* Executes the combined query.
|
|
9929
10723
|
*/
|
|
9930
10724
|
async execute() {
|
|
10725
|
+
this.#refuseCheckedScope();
|
|
9931
10726
|
if (!this.#config.backend) {
|
|
9932
10727
|
throw new Error(
|
|
9933
10728
|
"Cannot execute query: no backend configured. Use store.query() or pass a backend to createQueryBuilder()."
|
|
@@ -9952,6 +10747,7 @@ var UnionableQuery = class _UnionableQuery {
|
|
|
9952
10747
|
* transaction support.
|
|
9953
10748
|
*/
|
|
9954
10749
|
async executeOn(backend) {
|
|
10750
|
+
this.#refuseCheckedScope();
|
|
9955
10751
|
const ast = this.toAst();
|
|
9956
10752
|
if (composableQueryHasParameterReferences(ast)) {
|
|
9957
10753
|
throw new Error(
|
|
@@ -9962,7 +10758,40 @@ var UnionableQuery = class _UnionableQuery {
|
|
|
9962
10758
|
await this.#fetchRows(backend, ast, "recorded-batch-query")
|
|
9963
10759
|
);
|
|
9964
10760
|
}
|
|
10761
|
+
/** @internal Embedding contract consumed by `store.batchOnce()`. */
|
|
10762
|
+
compileOneStatementBatchItem() {
|
|
10763
|
+
this.#refuseCheckedScope();
|
|
10764
|
+
const ast = this.toAst();
|
|
10765
|
+
if (composableQueryHasParameterReferences(ast)) {
|
|
10766
|
+
throw new Error(
|
|
10767
|
+
"Query contains param() references. Bind prepared queries before batching."
|
|
10768
|
+
);
|
|
10769
|
+
}
|
|
10770
|
+
return {
|
|
10771
|
+
query: compileSetOperation2(
|
|
10772
|
+
ast,
|
|
10773
|
+
this.#config.graphId,
|
|
10774
|
+
this.#compileOptions()
|
|
10775
|
+
),
|
|
10776
|
+
outputNames: projectionOutputNames2(ast),
|
|
10777
|
+
orderBy: [],
|
|
10778
|
+
mapRows: (rows) => this.#mapRows(rows)
|
|
10779
|
+
};
|
|
10780
|
+
}
|
|
10781
|
+
#refuseCheckedScope() {
|
|
10782
|
+
if (getQueryBuilderInternalContext(this.#config).expectedSchemaVersion === void 0) {
|
|
10783
|
+
return;
|
|
10784
|
+
}
|
|
10785
|
+
throw new ConfigurationError(
|
|
10786
|
+
"Set operations are unavailable inside withCheckedReads().",
|
|
10787
|
+
{ operation: "withCheckedReads.setOperation" }
|
|
10788
|
+
);
|
|
10789
|
+
}
|
|
9965
10790
|
};
|
|
10791
|
+
function projectionOutputNames2(query) {
|
|
10792
|
+
if ("__type" in query) return projectionOutputNames2(query.left);
|
|
10793
|
+
return query.projection.fields.map((field2) => field2.outputName);
|
|
10794
|
+
}
|
|
9966
10795
|
|
|
9967
10796
|
// src/query/builder/aggregates.ts
|
|
9968
10797
|
function count(alias, field2) {
|
|
@@ -10190,6 +11019,9 @@ function createQueryBuilderWithContext(graphId, registry, options) {
|
|
|
10190
11019
|
},
|
|
10191
11020
|
...options?.runtimeKindTokenResolver !== void 0 && {
|
|
10192
11021
|
runtimeKindTokenResolver: options.runtimeKindTokenResolver
|
|
11022
|
+
},
|
|
11023
|
+
...options?.expectedSchemaVersion !== void 0 && {
|
|
11024
|
+
expectedSchemaVersion: options.expectedSchemaVersion
|
|
10193
11025
|
}
|
|
10194
11026
|
});
|
|
10195
11027
|
const sealed = options?.sealedCoordinate?.valid;
|
|
@@ -21965,6 +22797,20 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
21965
22797
|
query() {
|
|
21966
22798
|
return this.#createQueryForBackend(this.#backend);
|
|
21967
22799
|
}
|
|
22800
|
+
/**
|
|
22801
|
+
* Runs a read block whose fluent queries automatically use
|
|
22802
|
+
* `executeChecked(expectedSchemaVersion)` when `.execute()` is called.
|
|
22803
|
+
* A schema mismatch aborts the block with `SchemaChangedError`, so callers
|
|
22804
|
+
* can put one reload-and-retry boundary around the whole block.
|
|
22805
|
+
*/
|
|
22806
|
+
withCheckedReads(expectedSchemaVersion, fn) {
|
|
22807
|
+
const reads = {
|
|
22808
|
+
query: () => this.#createQueryForBackend(this.#backend, void 0, 1, {
|
|
22809
|
+
value: expectedSchemaVersion
|
|
22810
|
+
})
|
|
22811
|
+
};
|
|
22812
|
+
return fn(reads);
|
|
22813
|
+
}
|
|
21968
22814
|
/**
|
|
21969
22815
|
* Internal seam for {@link StoreView.query}: a query builder pinned to a
|
|
21970
22816
|
* view's {@link ReadCoordinate} with its temporal axis sealed
|
|
@@ -22360,6 +23206,70 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
22360
23206
|
return results;
|
|
22361
23207
|
});
|
|
22362
23208
|
}
|
|
23209
|
+
/**
|
|
23210
|
+
* Executes two or more independent relational queries as exactly one SQL
|
|
23211
|
+
* statement and returns their typed results in input order.
|
|
23212
|
+
*
|
|
23213
|
+
* Each read is embedded as a CTE and its rows are returned through a JSON
|
|
23214
|
+
* envelope. Unlike {@link batch}, this method opens no transaction and has
|
|
23215
|
+
* no sequential fallback: one call means one statement on every supported
|
|
23216
|
+
* backend. Fluent queries and the reads built by the callback are composable
|
|
23217
|
+
* here.
|
|
23218
|
+
*/
|
|
23219
|
+
async batchOnce(build) {
|
|
23220
|
+
const queries = build({
|
|
23221
|
+
neighbors: (source, options) => {
|
|
23222
|
+
this.#assertNeighborKinds(source, options.edges);
|
|
23223
|
+
return createNeighborRead(this.#neighborContext(), source, options);
|
|
23224
|
+
},
|
|
23225
|
+
countNeighbors: (source, options) => {
|
|
23226
|
+
this.#assertNeighborKinds(source, options.edges);
|
|
23227
|
+
return createNeighborCountRead(
|
|
23228
|
+
this.#neighborContext(),
|
|
23229
|
+
source,
|
|
23230
|
+
options
|
|
23231
|
+
);
|
|
23232
|
+
},
|
|
23233
|
+
subgraph: (rootId, options) => this.#createSubgraphRead(rootId, options)
|
|
23234
|
+
});
|
|
23235
|
+
return executeOneStatementBatch(
|
|
23236
|
+
this.#createHookedQueryBackend(this.#baseBackend),
|
|
23237
|
+
queries
|
|
23238
|
+
);
|
|
23239
|
+
}
|
|
23240
|
+
/** Reads hydrated adjacent nodes and their connecting edges in one statement. */
|
|
23241
|
+
async neighbors(source, options) {
|
|
23242
|
+
this.#assertNeighborKinds(source, options.edges);
|
|
23243
|
+
return readNeighbors(this.#neighborContext(), source, options);
|
|
23244
|
+
}
|
|
23245
|
+
/** Counts visible relationships to adjacent nodes without hydrating them. */
|
|
23246
|
+
async countNeighbors(source, options) {
|
|
23247
|
+
this.#assertNeighborKinds(source, options.edges);
|
|
23248
|
+
return countNeighbors(this.#neighborContext(), source, options);
|
|
23249
|
+
}
|
|
23250
|
+
#neighborContext() {
|
|
23251
|
+
return {
|
|
23252
|
+
graphId: this.graphId,
|
|
23253
|
+
backend: this.#createHookedQueryBackend(this.#backend),
|
|
23254
|
+
schema: this.#sqlSchema(),
|
|
23255
|
+
defaultTemporalMode: this.#graph.defaults.temporalMode,
|
|
23256
|
+
registry: this.#registry
|
|
23257
|
+
};
|
|
23258
|
+
}
|
|
23259
|
+
#assertNeighborKinds(source, edgeKinds) {
|
|
23260
|
+
if (!Object.hasOwn(this.#graph.nodes, source.kind)) {
|
|
23261
|
+
throw new KindNotFoundError(source.kind, "node", {
|
|
23262
|
+
graphId: this.graphId
|
|
23263
|
+
});
|
|
23264
|
+
}
|
|
23265
|
+
for (const edgeKind of edgeKinds) {
|
|
23266
|
+
if (!Object.hasOwn(this.#graph.edges, edgeKind)) {
|
|
23267
|
+
throw new KindNotFoundError(edgeKind, "edge", {
|
|
23268
|
+
graphId: this.graphId
|
|
23269
|
+
});
|
|
23270
|
+
}
|
|
23271
|
+
}
|
|
23272
|
+
}
|
|
22363
23273
|
/**
|
|
22364
23274
|
* Reads several edge kinds from heterogeneous source nodes with round trips
|
|
22365
23275
|
* independent of the number of licensed edge/source-kind combinations.
|
|
@@ -22520,6 +23430,23 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
22520
23430
|
});
|
|
22521
23431
|
return this.subgraphAtCoordinate(rootId, options);
|
|
22522
23432
|
}
|
|
23433
|
+
#createSubgraphRead(rootId, options) {
|
|
23434
|
+
assertNoRecordedCoordinate(options, {
|
|
23435
|
+
code: "SUBGRAPH_RECORDED_ASOF_INTERNAL_ONLY",
|
|
23436
|
+
message: "recordedAsOf is only available through store.asOfRecorded(...).subgraph(...).",
|
|
23437
|
+
suggestion: "Use store.asOfRecorded(recordedAt).subgraph(rootId, options) instead of passing recordedAsOf directly."
|
|
23438
|
+
});
|
|
23439
|
+
return createSubgraphRead({
|
|
23440
|
+
graph: this.#graph,
|
|
23441
|
+
graphId: this.graphId,
|
|
23442
|
+
rootId,
|
|
23443
|
+
backend: this.#createHookedQueryBackend(this.#baseBackend),
|
|
23444
|
+
dialect: getDialect(this.#backend.dialect),
|
|
23445
|
+
schema: this.#schema,
|
|
23446
|
+
recordedReadBinding: this.#recordedReadBinding,
|
|
23447
|
+
options
|
|
23448
|
+
});
|
|
23449
|
+
}
|
|
22523
23450
|
/**
|
|
22524
23451
|
* Internal seam for {@link StoreView} / {@link RecordedStoreView}: runs a
|
|
22525
23452
|
* subgraph with a coordinate already flattened into the options (including a
|
|
@@ -24463,7 +25390,7 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
24463
25390
|
}
|
|
24464
25391
|
};
|
|
24465
25392
|
}
|
|
24466
|
-
#createQueryForBackend(backend, sealedCoordinate, attempt = 1) {
|
|
25393
|
+
#createQueryForBackend(backend, sealedCoordinate, attempt = 1, expectedSchemaVersion) {
|
|
24467
25394
|
const queryBackend = this.#createHookedQueryBackend(backend, attempt);
|
|
24468
25395
|
return createInternalQueryBuilder(
|
|
24469
25396
|
this.graphId,
|
|
@@ -24479,7 +25406,8 @@ var StoreImplementation = class _StoreImplementation {
|
|
|
24479
25406
|
...this.#recordedReadBinding !== void 0 && {
|
|
24480
25407
|
recordedReadBinding: this.#recordedReadBinding
|
|
24481
25408
|
},
|
|
24482
|
-
...sealedCoordinate !== void 0 && { sealedCoordinate }
|
|
25409
|
+
...sealedCoordinate !== void 0 && { sealedCoordinate },
|
|
25410
|
+
...expectedSchemaVersion !== void 0 && { expectedSchemaVersion }
|
|
24483
25411
|
}
|
|
24484
25412
|
);
|
|
24485
25413
|
}
|
|
@@ -24920,5 +25848,5 @@ async function createVerifiedAdapterStore(graph, backend, options) {
|
|
|
24920
25848
|
}
|
|
24921
25849
|
|
|
24922
25850
|
export { CURRENT_ONLY_READ_NAMES, EDGE_TEMPORAL_READ_NAMES, ExecutableAggregateQuery, ExecutableQuery, IDENTITY_READ_NAMES, MAX_EXPLICIT_RECURSIVE_DEPTH, MAX_RECURSIVE_DEPTH, NODE_TEMPORAL_READ_NAMES, PreparedQuery, QueryBuilder, RecordedStoreView, StoreAnalysisCursorStaleError, StoreSearch, StoreView, UnionableQuery, avg, composeFragments, count, countDistinct, countDistinctEdges, countEdges, createAdapterStore, createAdapterStoreWithSchema, createFragment, createQueryBuilder, createStore, createStoreWithSchema, createVerifiedAdapterStore, createVerifiedStore, defineSubgraphProject, field, having, havingEq, havingGt, havingGte, havingLt, havingLte, limitFragment, max, min, offsetFragment, orderByFragment, sum };
|
|
24923
|
-
//# sourceMappingURL=chunk-
|
|
24924
|
-
//# sourceMappingURL=chunk-
|
|
25851
|
+
//# sourceMappingURL=chunk-MKQY4ZLZ.js.map
|
|
25852
|
+
//# sourceMappingURL=chunk-MKQY4ZLZ.js.map
|