@atomicmemory/core 1.0.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 +27 -0
- package/LICENSE +201 -0
- package/README.md +314 -0
- package/dist/app/bind-ephemeral.d.ts +18 -0
- package/dist/app/bind-ephemeral.js +22 -0
- package/dist/app/cors-headers.d.ts +12 -0
- package/dist/app/cors-headers.js +18 -0
- package/dist/app/create-app.d.ts +25 -0
- package/dist/app/create-app.js +156 -0
- package/dist/app/runtime-config-route-snapshot.d.ts +27 -0
- package/dist/app/runtime-config-route-snapshot.js +27 -0
- package/dist/app/runtime-container.d.ts +281 -0
- package/dist/app/runtime-container.js +297 -0
- package/dist/app/startup-checks.d.ts +28 -0
- package/dist/app/startup-checks.js +45 -0
- package/dist/bin.d.ts +17 -0
- package/dist/bin.js +128 -0
- package/dist/config.d.ts +680 -0
- package/dist/config.js +808 -0
- package/dist/db/agent-trust-repository.d.ts +49 -0
- package/dist/db/agent-trust-repository.js +66 -0
- package/dist/db/belief-edges-repository.d.ts +68 -0
- package/dist/db/belief-edges-repository.js +124 -0
- package/dist/db/claim-repository.d.ts +6 -0
- package/dist/db/claim-repository.js +4 -0
- package/dist/db/contradictions-repository.d.ts +56 -0
- package/dist/db/contradictions-repository.js +88 -0
- package/dist/db/document-chunk-repository.d.ts +48 -0
- package/dist/db/document-chunk-repository.js +145 -0
- package/dist/db/document-chunk-types.d.ts +35 -0
- package/dist/db/document-chunk-types.js +9 -0
- package/dist/db/document-list-cursor.d.ts +45 -0
- package/dist/db/document-list-cursor.js +111 -0
- package/dist/db/document-list-repository.d.ts +103 -0
- package/dist/db/document-list-repository.js +204 -0
- package/dist/db/entity-cards-repository.d.ts +37 -0
- package/dist/db/entity-cards-repository.js +46 -0
- package/dist/db/entity-values-repository.d.ts +26 -0
- package/dist/db/entity-values-repository.js +57 -0
- package/dist/db/link-repository.d.ts +30 -0
- package/dist/db/link-repository.js +54 -0
- package/dist/db/memory-repository.d.ts +163 -0
- package/dist/db/memory-repository.js +232 -0
- package/dist/db/migrate.d.ts +6 -0
- package/dist/db/migrate.js +36 -0
- package/dist/db/mmr.d.ts +14 -0
- package/dist/db/mmr.js +57 -0
- package/dist/db/passport-feed-repository.d.ts +91 -0
- package/dist/db/passport-feed-repository.js +198 -0
- package/dist/db/pg-episode-store.d.ts +19 -0
- package/dist/db/pg-episode-store.js +17 -0
- package/dist/db/pg-link-store.d.ts +17 -0
- package/dist/db/pg-link-store.js +14 -0
- package/dist/db/pg-memory-store.d.ts +68 -0
- package/dist/db/pg-memory-store.js +53 -0
- package/dist/db/pg-recap-store.d.ts +13 -0
- package/dist/db/pg-recap-store.js +19 -0
- package/dist/db/pg-representation-store.d.ts +17 -0
- package/dist/db/pg-representation-store.js +17 -0
- package/dist/db/pg-search-store.d.ts +29 -0
- package/dist/db/pg-search-store.js +47 -0
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +21 -0
- package/dist/db/ppr.d.ts +56 -0
- package/dist/db/ppr.js +178 -0
- package/dist/db/query-helpers.d.ts +44 -0
- package/dist/db/query-helpers.js +60 -0
- package/dist/db/raw-doc-artifact-sync.d.ts +128 -0
- package/dist/db/raw-doc-artifact-sync.js +259 -0
- package/dist/db/raw-document-blob-repository.d.ts +148 -0
- package/dist/db/raw-document-blob-repository.js +300 -0
- package/dist/db/raw-document-repository.d.ts +104 -0
- package/dist/db/raw-document-repository.js +410 -0
- package/dist/db/raw-document-status-repository.d.ts +122 -0
- package/dist/db/raw-document-status-repository.js +183 -0
- package/dist/db/raw-document-types.d.ts +236 -0
- package/dist/db/raw-document-types.js +10 -0
- package/dist/db/raw-storage-reconciliation-repository.d.ts +110 -0
- package/dist/db/raw-storage-reconciliation-repository.js +200 -0
- package/dist/db/reflection-jobs-repository.d.ts +33 -0
- package/dist/db/reflection-jobs-repository.js +48 -0
- package/dist/db/reflections-repository.d.ts +41 -0
- package/dist/db/reflections-repository.js +83 -0
- package/dist/db/repository-claims.d.ts +141 -0
- package/dist/db/repository-claims.js +376 -0
- package/dist/db/repository-deferred-audn.d.ts +33 -0
- package/dist/db/repository-deferred-audn.js +69 -0
- package/dist/db/repository-document-delete.d.ts +53 -0
- package/dist/db/repository-document-delete.js +156 -0
- package/dist/db/repository-entities.d.ts +114 -0
- package/dist/db/repository-entities.js +317 -0
- package/dist/db/repository-entity-attributes.d.ts +41 -0
- package/dist/db/repository-entity-attributes.js +65 -0
- package/dist/db/repository-entity-graph.d.ts +32 -0
- package/dist/db/repository-entity-graph.js +87 -0
- package/dist/db/repository-first-mentions.d.ts +41 -0
- package/dist/db/repository-first-mentions.js +79 -0
- package/dist/db/repository-lessons.d.ts +51 -0
- package/dist/db/repository-lessons.js +90 -0
- package/dist/db/repository-links.d.ts +26 -0
- package/dist/db/repository-links.js +105 -0
- package/dist/db/repository-observation.d.ts +26 -0
- package/dist/db/repository-observation.js +51 -0
- package/dist/db/repository-read.d.ts +56 -0
- package/dist/db/repository-read.js +271 -0
- package/dist/db/repository-recaps.d.ts +59 -0
- package/dist/db/repository-recaps.js +158 -0
- package/dist/db/repository-representations.d.ts +48 -0
- package/dist/db/repository-representations.js +162 -0
- package/dist/db/repository-temporal-state.d.ts +35 -0
- package/dist/db/repository-temporal-state.js +46 -0
- package/dist/db/repository-tll.d.ts +88 -0
- package/dist/db/repository-tll.js +179 -0
- package/dist/db/repository-types.d.ts +313 -0
- package/dist/db/repository-types.js +142 -0
- package/dist/db/repository-user-profiles.d.ts +17 -0
- package/dist/db/repository-user-profiles.js +28 -0
- package/dist/db/repository-vector-search.d.ts +33 -0
- package/dist/db/repository-vector-search.js +373 -0
- package/dist/db/repository-wipe.d.ts +34 -0
- package/dist/db/repository-wipe.js +94 -0
- package/dist/db/repository-write.d.ts +61 -0
- package/dist/db/repository-write.js +279 -0
- package/dist/db/schema.sql +1355 -0
- package/dist/db/storage-artifact-delete-tx.d.ts +56 -0
- package/dist/db/storage-artifact-delete-tx.js +123 -0
- package/dist/db/storage-artifact-providers.d.ts +21 -0
- package/dist/db/storage-artifact-providers.js +21 -0
- package/dist/db/storage-artifact-recovery-repository.d.ts +66 -0
- package/dist/db/storage-artifact-recovery-repository.js +58 -0
- package/dist/db/storage-artifact-repository.d.ts +329 -0
- package/dist/db/storage-artifact-repository.js +497 -0
- package/dist/db/stores.d.ts +220 -0
- package/dist/db/stores.js +12 -0
- package/dist/db/summaries-repository.d.ts +74 -0
- package/dist/db/summaries-repository.js +125 -0
- package/dist/eval/beam-10m-loader.d.ts +98 -0
- package/dist/eval/beam-10m-loader.js +128 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +17 -0
- package/dist/middleware/require-bearer.d.ts +27 -0
- package/dist/middleware/require-bearer.js +60 -0
- package/dist/middleware/validate-response.d.ts +33 -0
- package/dist/middleware/validate-response.js +55 -0
- package/dist/middleware/validate.d.ts +43 -0
- package/dist/middleware/validate.js +85 -0
- package/dist/routes/agents.d.ts +13 -0
- package/dist/routes/agents.js +89 -0
- package/dist/routes/document-response-formatters.d.ts +98 -0
- package/dist/routes/document-response-formatters.js +243 -0
- package/dist/routes/documents.d.ts +74 -0
- package/dist/routes/documents.js +425 -0
- package/dist/routes/memories.d.ts +29 -0
- package/dist/routes/memories.js +725 -0
- package/dist/routes/memory-response-formatters.d.ts +179 -0
- package/dist/routes/memory-response-formatters.js +210 -0
- package/dist/routes/public-raw-storage-metadata.d.ts +54 -0
- package/dist/routes/public-raw-storage-metadata.js +56 -0
- package/dist/routes/reflect.d.ts +14 -0
- package/dist/routes/reflect.js +19 -0
- package/dist/routes/response-schema-map.d.ts +14 -0
- package/dist/routes/response-schema-map.js +69 -0
- package/dist/routes/route-errors.d.ts +12 -0
- package/dist/routes/route-errors.js +30 -0
- package/dist/routes/storage-error-handlers.d.ts +34 -0
- package/dist/routes/storage-error-handlers.js +185 -0
- package/dist/routes/storage-response-formatters.d.ts +44 -0
- package/dist/routes/storage-response-formatters.js +155 -0
- package/dist/routes/storage.d.ts +38 -0
- package/dist/routes/storage.js +369 -0
- package/dist/routes/upstream-provider-errors.d.ts +19 -0
- package/dist/routes/upstream-provider-errors.js +95 -0
- package/dist/schemas/agents.d.ts +79 -0
- package/dist/schemas/agents.js +126 -0
- package/dist/schemas/common.d.ts +110 -0
- package/dist/schemas/common.js +190 -0
- package/dist/schemas/document-list-responses.d.ts +102 -0
- package/dist/schemas/document-list-responses.js +87 -0
- package/dist/schemas/document-list-schemas.d.ts +123 -0
- package/dist/schemas/document-list-schemas.js +174 -0
- package/dist/schemas/document-response-schemas.d.ts +610 -0
- package/dist/schemas/document-response-schemas.js +264 -0
- package/dist/schemas/document-status-envelope.d.ts +48 -0
- package/dist/schemas/document-status-envelope.js +54 -0
- package/dist/schemas/documents.d.ts +292 -0
- package/dist/schemas/documents.js +449 -0
- package/dist/schemas/errors.d.ts +75 -0
- package/dist/schemas/errors.js +105 -0
- package/dist/schemas/memories.d.ts +378 -0
- package/dist/schemas/memories.js +542 -0
- package/dist/schemas/openapi.d.ts +24 -0
- package/dist/schemas/openapi.js +1038 -0
- package/dist/schemas/response-scalars.d.ts +10 -0
- package/dist/schemas/response-scalars.js +10 -0
- package/dist/schemas/responses.d.ts +536 -0
- package/dist/schemas/responses.js +350 -0
- package/dist/schemas/search-response-parts.d.ts +97 -0
- package/dist/schemas/search-response-parts.js +103 -0
- package/dist/schemas/storage-schemas.d.ts +175 -0
- package/dist/schemas/storage-schemas.js +277 -0
- package/dist/schemas/zod-setup.d.ts +15 -0
- package/dist/schemas/zod-setup.js +17 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +57 -0
- package/dist/services/abstract-query-policy.d.ts +13 -0
- package/dist/services/abstract-query-policy.js +50 -0
- package/dist/services/affinity-clustering.d.ts +66 -0
- package/dist/services/affinity-clustering.js +125 -0
- package/dist/services/agentic-retrieval.d.ts +38 -0
- package/dist/services/agentic-retrieval.js +126 -0
- package/dist/services/answer-format.d.ts +56 -0
- package/dist/services/answer-format.js +118 -0
- package/dist/services/answer-rescue.d.ts +72 -0
- package/dist/services/answer-rescue.js +177 -0
- package/dist/services/answer-verifier.d.ts +24 -0
- package/dist/services/answer-verifier.js +73 -0
- package/dist/services/api-retry.d.ts +6 -0
- package/dist/services/api-retry.js +41 -0
- package/dist/services/assistant-turn-filter.d.ts +20 -0
- package/dist/services/assistant-turn-filter.js +69 -0
- package/dist/services/atomicmem-uri.d.ts +33 -0
- package/dist/services/atomicmem-uri.js +86 -0
- package/dist/services/audit-events.d.ts +54 -0
- package/dist/services/audit-events.js +56 -0
- package/dist/services/chunked-extraction.d.ts +21 -0
- package/dist/services/chunked-extraction.js +108 -0
- package/dist/services/claim-slotting.d.ts +27 -0
- package/dist/services/claim-slotting.js +38 -0
- package/dist/services/claude-code-llm.d.ts +19 -0
- package/dist/services/claude-code-llm.js +96 -0
- package/dist/services/composite-dedup.d.ts +50 -0
- package/dist/services/composite-dedup.js +153 -0
- package/dist/services/composite-grouping.d.ts +41 -0
- package/dist/services/composite-grouping.js +111 -0
- package/dist/services/composite-staleness.d.ts +20 -0
- package/dist/services/composite-staleness.js +50 -0
- package/dist/services/conciseness-preference.d.ts +14 -0
- package/dist/services/conciseness-preference.js +42 -0
- package/dist/services/conflict-policy.d.ts +20 -0
- package/dist/services/conflict-policy.js +335 -0
- package/dist/services/consensus-extraction.d.ts +39 -0
- package/dist/services/consensus-extraction.js +147 -0
- package/dist/services/consensus-validation.d.ts +52 -0
- package/dist/services/consensus-validation.js +206 -0
- package/dist/services/consolidation-service.d.ts +60 -0
- package/dist/services/consolidation-service.js +171 -0
- package/dist/services/content-detection.d.ts +18 -0
- package/dist/services/content-detection.js +25 -0
- package/dist/services/contradiction-surfacing.d.ts +62 -0
- package/dist/services/contradiction-surfacing.js +111 -0
- package/dist/services/cost-telemetry.d.ts +39 -0
- package/dist/services/cost-telemetry.js +58 -0
- package/dist/services/counter-evidence.d.ts +34 -0
- package/dist/services/counter-evidence.js +92 -0
- package/dist/services/current-state-ranking.d.ts +21 -0
- package/dist/services/current-state-ranking.js +152 -0
- package/dist/services/deferred-audn.d.ts +47 -0
- package/dist/services/deferred-audn.js +162 -0
- package/dist/services/document-chunker.d.ts +50 -0
- package/dist/services/document-chunker.js +153 -0
- package/dist/services/document-failure-markers.d.ts +91 -0
- package/dist/services/document-failure-markers.js +305 -0
- package/dist/services/document-indexer.d.ts +122 -0
- package/dist/services/document-indexer.js +405 -0
- package/dist/services/document-service.d.ts +245 -0
- package/dist/services/document-service.js +325 -0
- package/dist/services/document-upload-artifact-sync.d.ts +80 -0
- package/dist/services/document-upload-artifact-sync.js +162 -0
- package/dist/services/document-upload-beta2-recovery.d.ts +72 -0
- package/dist/services/document-upload-beta2-recovery.js +94 -0
- package/dist/services/document-upload.d.ts +44 -0
- package/dist/services/document-upload.js +353 -0
- package/dist/services/embedding.d.ts +57 -0
- package/dist/services/embedding.js +416 -0
- package/dist/services/entity-attribute-extractor.d.ts +34 -0
- package/dist/services/entity-attribute-extractor.js +117 -0
- package/dist/services/entity-card-synthesis.d.ts +54 -0
- package/dist/services/entity-card-synthesis.js +92 -0
- package/dist/services/entity-dedup.d.ts +9 -0
- package/dist/services/entity-dedup.js +14 -0
- package/dist/services/entity-graph.d.ts +17 -0
- package/dist/services/entity-graph.js +135 -0
- package/dist/services/entropy-gate.d.ts +52 -0
- package/dist/services/entropy-gate.js +56 -0
- package/dist/services/episode-fetcher.d.ts +47 -0
- package/dist/services/episode-fetcher.js +128 -0
- package/dist/services/event-anchor-facts.d.ts +8 -0
- package/dist/services/event-anchor-facts.js +205 -0
- package/dist/services/event-chain-detector.d.ts +52 -0
- package/dist/services/event-chain-detector.js +83 -0
- package/dist/services/extraction-cache.d.ts +9 -0
- package/dist/services/extraction-cache.js +54 -0
- package/dist/services/extraction-enrichment.d.ts +9 -0
- package/dist/services/extraction-enrichment.js +223 -0
- package/dist/services/extraction.d.ts +69 -0
- package/dist/services/extraction.js +596 -0
- package/dist/services/fact-normalization.d.ts +12 -0
- package/dist/services/fact-normalization.js +248 -0
- package/dist/services/filecoin-observability.d.ts +127 -0
- package/dist/services/filecoin-observability.js +200 -0
- package/dist/services/first-mention-service.d.ts +76 -0
- package/dist/services/first-mention-service.js +186 -0
- package/dist/services/hierarchical-retrieval.d.ts +49 -0
- package/dist/services/hierarchical-retrieval.js +50 -0
- package/dist/services/ingest-fact-pipeline.d.ts +32 -0
- package/dist/services/ingest-fact-pipeline.js +212 -0
- package/dist/services/ingest-post-write.d.ts +50 -0
- package/dist/services/ingest-post-write.js +117 -0
- package/dist/services/ingest-trace.d.ts +32 -0
- package/dist/services/ingest-trace.js +60 -0
- package/dist/services/input-sanitizer.d.ts +41 -0
- package/dist/services/input-sanitizer.js +135 -0
- package/dist/services/iterative-retrieval.d.ts +26 -0
- package/dist/services/iterative-retrieval.js +139 -0
- package/dist/services/keyword-expansion.d.ts +10 -0
- package/dist/services/keyword-expansion.js +26 -0
- package/dist/services/lesson-service.d.ts +68 -0
- package/dist/services/lesson-service.js +178 -0
- package/dist/services/literal-extractor.d.ts +16 -0
- package/dist/services/literal-extractor.js +74 -0
- package/dist/services/literal-list-protection.d.ts +17 -0
- package/dist/services/literal-list-protection.js +134 -0
- package/dist/services/literal-query-expansion.d.ts +20 -0
- package/dist/services/literal-query-expansion.js +181 -0
- package/dist/services/llm.d.ts +61 -0
- package/dist/services/llm.js +265 -0
- package/dist/services/memcell-projection.d.ts +17 -0
- package/dist/services/memcell-projection.js +41 -0
- package/dist/services/memory-audn.d.ts +43 -0
- package/dist/services/memory-audn.js +419 -0
- package/dist/services/memory-crud.d.ts +93 -0
- package/dist/services/memory-crud.js +255 -0
- package/dist/services/memory-ingest.d.ts +21 -0
- package/dist/services/memory-ingest.js +249 -0
- package/dist/services/memory-lifecycle.d.ts +75 -0
- package/dist/services/memory-lifecycle.js +108 -0
- package/dist/services/memory-lineage.d.ts +181 -0
- package/dist/services/memory-lineage.js +232 -0
- package/dist/services/memory-network.d.ts +40 -0
- package/dist/services/memory-network.js +75 -0
- package/dist/services/memory-search-types.d.ts +25 -0
- package/dist/services/memory-search-types.js +10 -0
- package/dist/services/memory-search.d.ts +48 -0
- package/dist/services/memory-search.js +505 -0
- package/dist/services/memory-service-types.d.ts +371 -0
- package/dist/services/memory-service-types.js +8 -0
- package/dist/services/memory-service.d.ts +152 -0
- package/dist/services/memory-service.js +225 -0
- package/dist/services/memory-storage.d.ts +33 -0
- package/dist/services/memory-storage.js +328 -0
- package/dist/services/msr-aggregator.d.ts +38 -0
- package/dist/services/msr-aggregator.js +97 -0
- package/dist/services/msr-detector.d.ts +35 -0
- package/dist/services/msr-detector.js +65 -0
- package/dist/services/namespace-retrieval.d.ts +60 -0
- package/dist/services/namespace-retrieval.js +180 -0
- package/dist/services/observation-date-extraction.d.ts +12 -0
- package/dist/services/observation-date-extraction.js +50 -0
- package/dist/services/observation-service.d.ts +27 -0
- package/dist/services/observation-service.js +84 -0
- package/dist/services/packaging-observability.d.ts +29 -0
- package/dist/services/packaging-observability.js +146 -0
- package/dist/services/query-expansion.d.ts +83 -0
- package/dist/services/query-expansion.js +242 -0
- package/dist/services/query-keyword-matches.d.ts +6 -0
- package/dist/services/query-keyword-matches.js +56 -0
- package/dist/services/query-term-visibility.d.ts +28 -0
- package/dist/services/query-term-visibility.js +100 -0
- package/dist/services/quick-extraction.d.ts +25 -0
- package/dist/services/quick-extraction.js +431 -0
- package/dist/services/quoted-entity-extraction.d.ts +10 -0
- package/dist/services/quoted-entity-extraction.js +161 -0
- package/dist/services/raw-storage-reconciler-backoff.d.ts +8 -0
- package/dist/services/raw-storage-reconciler-backoff.js +14 -0
- package/dist/services/raw-storage-reconciler-scheduler.d.ts +29 -0
- package/dist/services/raw-storage-reconciler-scheduler.js +43 -0
- package/dist/services/raw-storage-reconciler.d.ts +71 -0
- package/dist/services/raw-storage-reconciler.js +278 -0
- package/dist/services/recap-builder.d.ts +49 -0
- package/dist/services/recap-builder.js +157 -0
- package/dist/services/reflect-jobs.d.ts +23 -0
- package/dist/services/reflect-jobs.js +36 -0
- package/dist/services/reflect-prompts.d.ts +71 -0
- package/dist/services/reflect-prompts.js +99 -0
- package/dist/services/reflect-retrieval.d.ts +33 -0
- package/dist/services/reflect-retrieval.js +30 -0
- package/dist/services/reflect.d.ts +49 -0
- package/dist/services/reflect.js +84 -0
- package/dist/services/relative-temporal.d.ts +14 -0
- package/dist/services/relative-temporal.js +163 -0
- package/dist/services/relevance-policy.d.ts +37 -0
- package/dist/services/relevance-policy.js +109 -0
- package/dist/services/rerank.d.ts +32 -0
- package/dist/services/rerank.js +118 -0
- package/dist/services/reranker.d.ts +20 -0
- package/dist/services/reranker.js +99 -0
- package/dist/services/retrieval-channel-rules.d.ts +34 -0
- package/dist/services/retrieval-channel-rules.js +41 -0
- package/dist/services/retrieval-config-overlay.d.ts +36 -0
- package/dist/services/retrieval-config-overlay.js +44 -0
- package/dist/services/retrieval-format.d.ts +119 -0
- package/dist/services/retrieval-format.js +559 -0
- package/dist/services/retrieval-policy.d.ts +69 -0
- package/dist/services/retrieval-policy.js +275 -0
- package/dist/services/retrieval-profiles.d.ts +37 -0
- package/dist/services/retrieval-profiles.js +90 -0
- package/dist/services/retrieval-side-effects.d.ts +14 -0
- package/dist/services/retrieval-side-effects.js +26 -0
- package/dist/services/retrieval-trace.d.ts +108 -0
- package/dist/services/retrieval-trace.js +147 -0
- package/dist/services/rrf-fusion.d.ts +18 -0
- package/dist/services/rrf-fusion.js +34 -0
- package/dist/services/search-pipeline.d.ts +71 -0
- package/dist/services/search-pipeline.js +788 -0
- package/dist/services/session-date.d.ts +20 -0
- package/dist/services/session-date.js +61 -0
- package/dist/services/session-packaging.d.ts +53 -0
- package/dist/services/session-packaging.js +182 -0
- package/dist/services/session-summary-generator.d.ts +53 -0
- package/dist/services/session-summary-generator.js +134 -0
- package/dist/services/specialists/cr-specialist.d.ts +52 -0
- package/dist/services/specialists/cr-specialist.js +121 -0
- package/dist/services/specialists/dispatch.d.ts +53 -0
- package/dist/services/specialists/dispatch.js +102 -0
- package/dist/services/specialists/ie-ku-specialist.d.ts +37 -0
- package/dist/services/specialists/ie-ku-specialist.js +63 -0
- package/dist/services/specialists/msr-specialist.d.ts +61 -0
- package/dist/services/specialists/msr-specialist.js +162 -0
- package/dist/services/specialists/tr-specialist.d.ts +37 -0
- package/dist/services/specialists/tr-specialist.js +146 -0
- package/dist/services/storage-key-prefix.d.ts +42 -0
- package/dist/services/storage-key-prefix.js +45 -0
- package/dist/services/storage-put-recovery.d.ts +71 -0
- package/dist/services/storage-put-recovery.js +269 -0
- package/dist/services/storage-service-errors.d.ts +124 -0
- package/dist/services/storage-service-errors.js +189 -0
- package/dist/services/storage-service.d.ts +176 -0
- package/dist/services/storage-service.js +423 -0
- package/dist/services/subject-aware-ranking.d.ts +19 -0
- package/dist/services/subject-aware-ranking.js +161 -0
- package/dist/services/supplemental-extraction.d.ts +7 -0
- package/dist/services/supplemental-extraction.js +116 -0
- package/dist/services/tbc-execution.d.ts +49 -0
- package/dist/services/tbc-execution.js +284 -0
- package/dist/services/temporal-classifier.d.ts +56 -0
- package/dist/services/temporal-classifier.js +94 -0
- package/dist/services/temporal-endpoint-evidence.d.ts +12 -0
- package/dist/services/temporal-endpoint-evidence.js +313 -0
- package/dist/services/temporal-fingerprint.d.ts +6 -0
- package/dist/services/temporal-fingerprint.js +12 -0
- package/dist/services/temporal-format.d.ts +9 -0
- package/dist/services/temporal-format.js +21 -0
- package/dist/services/temporal-intent.d.ts +39 -0
- package/dist/services/temporal-intent.js +78 -0
- package/dist/services/temporal-query-constraints.d.ts +16 -0
- package/dist/services/temporal-query-constraints.js +107 -0
- package/dist/services/temporal-query-expansion.d.ts +14 -0
- package/dist/services/temporal-query-expansion.js +131 -0
- package/dist/services/temporal-rerank.d.ts +22 -0
- package/dist/services/temporal-rerank.js +47 -0
- package/dist/services/temporal-result-protection.d.ts +7 -0
- package/dist/services/temporal-result-protection.js +60 -0
- package/dist/services/temporal-state-write.d.ts +57 -0
- package/dist/services/temporal-state-write.js +45 -0
- package/dist/services/tiered-context.d.ts +87 -0
- package/dist/services/tiered-context.js +214 -0
- package/dist/services/tiered-loading.d.ts +88 -0
- package/dist/services/tiered-loading.js +263 -0
- package/dist/services/timeline-pack.d.ts +36 -0
- package/dist/services/timeline-pack.js +50 -0
- package/dist/services/timing.d.ts +13 -0
- package/dist/services/timing.js +72 -0
- package/dist/services/tll-augmentation.d.ts +20 -0
- package/dist/services/tll-augmentation.js +125 -0
- package/dist/services/tll-retrieval.d.ts +55 -0
- package/dist/services/tll-retrieval.js +101 -0
- package/dist/services/topic-abstraction.d.ts +36 -0
- package/dist/services/topic-abstraction.js +105 -0
- package/dist/services/trust-scoring.d.ts +43 -0
- package/dist/services/trust-scoring.js +89 -0
- package/dist/services/typed-belief-calculus.d.ts +126 -0
- package/dist/services/typed-belief-calculus.js +204 -0
- package/dist/services/upload-config.d.ts +34 -0
- package/dist/services/upload-config.js +23 -0
- package/dist/services/upload-decision.d.ts +65 -0
- package/dist/services/upload-decision.js +98 -0
- package/dist/services/upload-helpers.d.ts +107 -0
- package/dist/services/upload-helpers.js +148 -0
- package/dist/services/user-profile-builder.d.ts +22 -0
- package/dist/services/user-profile-builder.js +109 -0
- package/dist/services/voyage-embedding.d.ts +22 -0
- package/dist/services/voyage-embedding.js +77 -0
- package/dist/services/write-security.d.ts +31 -0
- package/dist/services/write-security.js +64 -0
- package/dist/storage/artifact-public-redaction.d.ts +34 -0
- package/dist/storage/artifact-public-redaction.js +83 -0
- package/dist/storage/cleanup.d.ts +103 -0
- package/dist/storage/cleanup.js +138 -0
- package/dist/storage/codec-factory.d.ts +17 -0
- package/dist/storage/codec-factory.js +33 -0
- package/dist/storage/codecs/aes-gcm-codec.d.ts +44 -0
- package/dist/storage/codecs/aes-gcm-codec.js +108 -0
- package/dist/storage/codecs/noop-codec.d.ts +16 -0
- package/dist/storage/codecs/noop-codec.js +23 -0
- package/dist/storage/factory.d.ts +44 -0
- package/dist/storage/factory.js +99 -0
- package/dist/storage/filecoin-cid-validation.d.ts +82 -0
- package/dist/storage/filecoin-cid-validation.js +122 -0
- package/dist/storage/filecoin-public-metadata.d.ts +73 -0
- package/dist/storage/filecoin-public-metadata.js +110 -0
- package/dist/storage/local-fs-store.d.ts +39 -0
- package/dist/storage/local-fs-store.js +145 -0
- package/dist/storage/pointer-uri-allowlist.d.ts +38 -0
- package/dist/storage/pointer-uri-allowlist.js +70 -0
- package/dist/storage/provider-metadata-projection.d.ts +27 -0
- package/dist/storage/provider-metadata-projection.js +68 -0
- package/dist/storage/providers/filecoin/backend.d.ts +42 -0
- package/dist/storage/providers/filecoin/backend.js +250 -0
- package/dist/storage/providers/filecoin/config.d.ts +70 -0
- package/dist/storage/providers/filecoin/config.js +275 -0
- package/dist/storage/providers/filecoin/errors.d.ts +45 -0
- package/dist/storage/providers/filecoin/errors.js +56 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.d.ts +78 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.js +155 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.d.ts +92 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.js +199 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.d.ts +58 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.js +103 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.d.ts +30 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.js +53 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.d.ts +111 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.js +87 -0
- package/dist/storage/providers/filecoin/hints.d.ts +71 -0
- package/dist/storage/providers/filecoin/hints.js +123 -0
- package/dist/storage/providers/filecoin/index.d.ts +51 -0
- package/dist/storage/providers/filecoin/index.js +103 -0
- package/dist/storage/providers/filecoin/ipfs-cid.d.ts +50 -0
- package/dist/storage/providers/filecoin/ipfs-cid.js +64 -0
- package/dist/storage/providers/filecoin/metadata.d.ts +72 -0
- package/dist/storage/providers/filecoin/metadata.js +137 -0
- package/dist/storage/providers/filecoin/piece-cid.d.ts +48 -0
- package/dist/storage/providers/filecoin/piece-cid.js +57 -0
- package/dist/storage/providers/filecoin/provider-client.d.ts +234 -0
- package/dist/storage/providers/filecoin/provider-client.js +27 -0
- package/dist/storage/providers/filecoin/readiness.d.ts +62 -0
- package/dist/storage/providers/filecoin/readiness.js +85 -0
- package/dist/storage/providers/filecoin/retriever.d.ts +82 -0
- package/dist/storage/providers/filecoin/retriever.js +63 -0
- package/dist/storage/providers/filecoin/skeleton-client.d.ts +36 -0
- package/dist/storage/providers/filecoin/skeleton-client.js +55 -0
- package/dist/storage/providers/filecoin/synapse-client.d.ts +169 -0
- package/dist/storage/providers/filecoin/synapse-client.js +343 -0
- package/dist/storage/providers/filecoin/synapse-construction.d.ts +26 -0
- package/dist/storage/providers/filecoin/synapse-construction.js +47 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.d.ts +23 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.js +49 -0
- package/dist/storage/providers/filecoin/synapse-readiness.d.ts +37 -0
- package/dist/storage/providers/filecoin/synapse-readiness.js +231 -0
- package/dist/storage/providers/filecoin/uri.d.ts +49 -0
- package/dist/storage/providers/filecoin/uri.js +84 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.d.ts +77 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.js +196 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.d.ts +54 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.js +81 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.d.ts +71 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.js +94 -0
- package/dist/storage/raw-content-codec.d.ts +89 -0
- package/dist/storage/raw-content-codec.js +47 -0
- package/dist/storage/raw-content-store-backend-adapter.d.ts +28 -0
- package/dist/storage/raw-content-store-backend-adapter.js +67 -0
- package/dist/storage/raw-content-store.d.ts +228 -0
- package/dist/storage/raw-content-store.js +27 -0
- package/dist/storage/s3-store.d.ts +42 -0
- package/dist/storage/s3-store.js +181 -0
- package/dist/storage/storage-backend-registry.d.ts +58 -0
- package/dist/storage/storage-backend-registry.js +56 -0
- package/dist/storage/storage-backend.d.ts +82 -0
- package/dist/storage/storage-backend.js +14 -0
- package/dist/storage/storage-capabilities.d.ts +56 -0
- package/dist/storage/storage-capabilities.js +170 -0
- package/dist/storage/store-registry.d.ts +67 -0
- package/dist/storage/store-registry.js +77 -0
- package/dist/vector-math.d.ts +15 -0
- package/dist/vector-math.js +31 -0
- package/dist/xml-escape.d.ts +5 -0
- package/dist/xml-escape.js +7 -0
- package/openapi.json +15395 -0
- package/openapi.yaml +10794 -0
- package/package.json +119 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Real Synapse-backed readiness probes.
|
|
3
|
+
*
|
|
4
|
+
* Lives in its own module to keep `synapse-client.ts` under the
|
|
5
|
+
* workspace 400-LOC cap. Exports `synapseCheckReadiness(synapse,
|
|
6
|
+
* options, network)` which runs the non-mutating probes
|
|
7
|
+
* documented in `FILECOIN_READINESS_REQUIRED_CHECKS` and returns
|
|
8
|
+
* the closed-shape check list `FilecoinProviderClient.checkReadiness`
|
|
9
|
+
* promises.
|
|
10
|
+
*
|
|
11
|
+
* All probes are non-mutating SDK reads:
|
|
12
|
+
* - `storage.getStorageInfo()` — pricing / providers / allowances / service bounds
|
|
13
|
+
* - `storage.getUploadCosts()` — canonical "ready to upload at this size" probe
|
|
14
|
+
* - `storage.findDataSets()` — owned data-set inventory (no creation)
|
|
15
|
+
* - `client.getChainId()` — connected-chain id
|
|
16
|
+
*
|
|
17
|
+
* Sanitization rule: NO call inside this module ever lets a wallet
|
|
18
|
+
* address, balance numeric, allowance numeric, provider auth payload,
|
|
19
|
+
* or raw vendor error message escape. Every check carries a stable
|
|
20
|
+
* `errorCode` from the closed set documented inline below.
|
|
21
|
+
*/
|
|
22
|
+
import { calibration, mainnet } from '@filoz/synapse-sdk';
|
|
23
|
+
/**
|
|
24
|
+
* Run the documented Synapse readiness probes. Returns the closed-
|
|
25
|
+
* shape check list in `FILECOIN_READINESS_REQUIRED_CHECKS` order.
|
|
26
|
+
* All calls are non-mutating: `getStorageInfo()`,
|
|
27
|
+
* `getUploadCosts()`, `findDataSets()`, `client.getChainId()`. No
|
|
28
|
+
* upload, no data-set creation, no payment side-effects.
|
|
29
|
+
*/
|
|
30
|
+
export async function synapseCheckReadiness(synapse, options, network) {
|
|
31
|
+
const storage = await fetchStorageInfo(synapse);
|
|
32
|
+
const chain = await chainCheck(synapse, network, storage.errorCode);
|
|
33
|
+
const payment = await paymentCheck(synapse, options, storage);
|
|
34
|
+
const dataSet = await dataSetCheck(synapse, storage.errorCode);
|
|
35
|
+
return [
|
|
36
|
+
networkReachableCheck(storage.errorCode),
|
|
37
|
+
keyLoadableCheck(),
|
|
38
|
+
chain,
|
|
39
|
+
payment,
|
|
40
|
+
providerIdsCheck(options.providerIds, storage.info, storage.errorCode),
|
|
41
|
+
dataSet,
|
|
42
|
+
retrievalAvailableCheck(),
|
|
43
|
+
uploadSizeBoundsCheck(options, storage.info, storage.errorCode),
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
async function fetchStorageInfo(synapse) {
|
|
47
|
+
try {
|
|
48
|
+
const info = await synapse.storage.getStorageInfo();
|
|
49
|
+
return { info, errorCode: null };
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return { info: null, errorCode: 'network_unreachable' };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function chainCheck(synapse, network, storageError) {
|
|
56
|
+
if (storageError !== null)
|
|
57
|
+
return blockedByNetwork('account_on_expected_network');
|
|
58
|
+
const expected = expectedChainIdFor(network);
|
|
59
|
+
let actual;
|
|
60
|
+
try {
|
|
61
|
+
actual = await synapse.client.getChainId();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return failed('account_on_expected_network', 'network_unreachable');
|
|
65
|
+
}
|
|
66
|
+
if (BigInt(actual) === expected)
|
|
67
|
+
return passed('account_on_expected_network');
|
|
68
|
+
return failed('account_on_expected_network', 'chain_mismatch');
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Map the AtomicMemory readiness network to the canonical Synapse
|
|
72
|
+
* chain id. The SDK exports the chain objects directly; importing
|
|
73
|
+
* them here means a future SDK that re-numbers calibration or
|
|
74
|
+
* adds a new network surfaces at the boundary, not silently.
|
|
75
|
+
*/
|
|
76
|
+
function expectedChainIdFor(network) {
|
|
77
|
+
switch (network) {
|
|
78
|
+
case 'calibration':
|
|
79
|
+
return BigInt(calibration.id);
|
|
80
|
+
case 'mainnet':
|
|
81
|
+
return BigInt(mainnet.id);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function dataSetCheck(synapse, storageError) {
|
|
85
|
+
if (storageError !== null)
|
|
86
|
+
return blockedByNetwork('data_set_available');
|
|
87
|
+
try {
|
|
88
|
+
const sets = await synapse.storage.findDataSets();
|
|
89
|
+
if (sets.length === 0) {
|
|
90
|
+
// Cold-start state — first upload creates one. Reported as
|
|
91
|
+
// `'unknown'` rather than `'failed'` because the absence is
|
|
92
|
+
// expected before any upload.
|
|
93
|
+
return {
|
|
94
|
+
name: 'data_set_available',
|
|
95
|
+
status: 'unknown',
|
|
96
|
+
errorCode: 'data_set_not_yet_created',
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return passed('data_set_available');
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return failed('data_set_available', 'network_unreachable');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function networkReachableCheck(storageError) {
|
|
106
|
+
if (storageError === null)
|
|
107
|
+
return passed('network_reachable');
|
|
108
|
+
return failed('network_reachable', storageError);
|
|
109
|
+
}
|
|
110
|
+
function keyLoadableCheck() {
|
|
111
|
+
// The Synapse instance was constructed via `buildSynapse`, which
|
|
112
|
+
// calls `viem/accounts.privateKeyToAccount`. Reaching this code
|
|
113
|
+
// implies the key syntactically loaded; readiness reports the
|
|
114
|
+
// check as `'passed'` rather than re-probing the key material.
|
|
115
|
+
return passed('key_loadable');
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Payment readiness in three layers:
|
|
119
|
+
* 1. If `getStorageInfo` failed upstream, cascade to
|
|
120
|
+
* `blocked_by_network_unreachable`.
|
|
121
|
+
* 2. Use the cheap `allowances` snapshot to detect obvious
|
|
122
|
+
* mis-configuration (null / not approved / exhausted) — fail
|
|
123
|
+
* fast with a precise code.
|
|
124
|
+
* 3. If the snapshot looks OK, issue `getUploadCosts(minUploadSize)`
|
|
125
|
+
* as the canonical "are you ready for a min-size upload"
|
|
126
|
+
* probe. `result.ready === true` → passed;
|
|
127
|
+
* `result.ready === false` →
|
|
128
|
+
* `payment_min_upload_cost_insufficient`; throw →
|
|
129
|
+
* `blocked_by_network_unreachable`. NEVER returns passed
|
|
130
|
+
* without the SDK affirming `ready`.
|
|
131
|
+
*/
|
|
132
|
+
async function paymentCheck(synapse, options, storage) {
|
|
133
|
+
if (storage.errorCode !== null)
|
|
134
|
+
return blockedByNetwork('payment_covers_minimum_upload');
|
|
135
|
+
const info = storage.info;
|
|
136
|
+
if (info === null || info.allowances === null) {
|
|
137
|
+
return failed('payment_covers_minimum_upload', 'payment_allowance_not_configured');
|
|
138
|
+
}
|
|
139
|
+
const a = info.allowances;
|
|
140
|
+
if (!a.isApproved)
|
|
141
|
+
return failed('payment_covers_minimum_upload', 'payment_allowance_not_approved');
|
|
142
|
+
if (a.rateAllowance <= a.rateUsed) {
|
|
143
|
+
return failed('payment_covers_minimum_upload', 'payment_rate_allowance_exhausted');
|
|
144
|
+
}
|
|
145
|
+
if (a.lockupAllowance <= a.lockupUsed) {
|
|
146
|
+
return failed('payment_covers_minimum_upload', 'payment_lockup_allowance_exhausted');
|
|
147
|
+
}
|
|
148
|
+
return probeMinUploadCost(synapse, info, options);
|
|
149
|
+
}
|
|
150
|
+
async function probeMinUploadCost(synapse, info, options) {
|
|
151
|
+
const dataSize = BigInt(info.serviceParameters.minUploadSize);
|
|
152
|
+
let costs;
|
|
153
|
+
try {
|
|
154
|
+
costs = await synapse.storage.getUploadCosts({
|
|
155
|
+
dataSize,
|
|
156
|
+
...(options.withCdn !== undefined ? { withCDN: options.withCdn } : {}),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return blockedByNetwork('payment_covers_minimum_upload');
|
|
161
|
+
}
|
|
162
|
+
if (costs.ready)
|
|
163
|
+
return passed('payment_covers_minimum_upload');
|
|
164
|
+
return failed('payment_covers_minimum_upload', 'payment_min_upload_cost_insufficient');
|
|
165
|
+
}
|
|
166
|
+
function providerIdsCheck(configured, info, storageError) {
|
|
167
|
+
if (storageError !== null)
|
|
168
|
+
return blockedByNetwork('provider_ids_reachable');
|
|
169
|
+
// If no operator-pinned providers, the SDK picks at upload time;
|
|
170
|
+
// we only verify the SDK saw at least one provider.
|
|
171
|
+
if (configured.length === 0) {
|
|
172
|
+
if (info && info.providers.length === 0) {
|
|
173
|
+
return failed('provider_ids_reachable', 'no_providers_listed');
|
|
174
|
+
}
|
|
175
|
+
return passed('provider_ids_reachable');
|
|
176
|
+
}
|
|
177
|
+
if (info === null)
|
|
178
|
+
return blockedByNetwork('provider_ids_reachable');
|
|
179
|
+
const listed = new Set(info.providers.map((p) => p.id.toString()));
|
|
180
|
+
for (const id of configured) {
|
|
181
|
+
if (!listed.has(id))
|
|
182
|
+
return failed('provider_ids_reachable', 'provider_id_not_listed');
|
|
183
|
+
}
|
|
184
|
+
return passed('provider_ids_reachable');
|
|
185
|
+
}
|
|
186
|
+
function retrievalAvailableCheck() {
|
|
187
|
+
// No non-mutating retrieval primitive exposed on `StorageManager`
|
|
188
|
+
// in this SDK release: `pieceStatus` is per-context, and the cheap
|
|
189
|
+
// "is the SDK retrieval path healthy" question has no SDK answer.
|
|
190
|
+
// Reported as
|
|
191
|
+
// `'unknown' / 'not_implemented'` (truly not yet implemented) so
|
|
192
|
+
// operators can distinguish this from cascade-blocked checks.
|
|
193
|
+
return notImplemented('retrieval_available');
|
|
194
|
+
}
|
|
195
|
+
function uploadSizeBoundsCheck(options, info, storageError) {
|
|
196
|
+
if (storageError !== null)
|
|
197
|
+
return blockedByNetwork('upload_size_bounds_compatible');
|
|
198
|
+
if (info === null)
|
|
199
|
+
return blockedByNetwork('upload_size_bounds_compatible');
|
|
200
|
+
const svcMin = info.serviceParameters.minUploadSize;
|
|
201
|
+
const svcMax = info.serviceParameters.maxUploadSize;
|
|
202
|
+
if (svcMin > svcMax) {
|
|
203
|
+
return failed('upload_size_bounds_compatible', 'upload_size_bounds_invalid');
|
|
204
|
+
}
|
|
205
|
+
if (options.maxUploadBytes !== null && options.maxUploadBytes > svcMax) {
|
|
206
|
+
return failed('upload_size_bounds_compatible', 'max_upload_exceeds_service');
|
|
207
|
+
}
|
|
208
|
+
if (options.minUploadBytes !== null && options.minUploadBytes < svcMin) {
|
|
209
|
+
return failed('upload_size_bounds_compatible', 'min_upload_below_service');
|
|
210
|
+
}
|
|
211
|
+
return passed('upload_size_bounds_compatible');
|
|
212
|
+
}
|
|
213
|
+
function passed(name) {
|
|
214
|
+
return { name, status: 'passed' };
|
|
215
|
+
}
|
|
216
|
+
function failed(name, errorCode) {
|
|
217
|
+
return { name, status: 'failed', errorCode };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Unknown because a more-fundamental upstream check failed (almost
|
|
221
|
+
* always `network_reachable`). Distinguished from `notImplemented`
|
|
222
|
+
* via the `blocked_by_network_unreachable` code so operators see
|
|
223
|
+
* "this couldn't be evaluated, not 'we haven't built it yet'".
|
|
224
|
+
*/
|
|
225
|
+
function blockedByNetwork(name) {
|
|
226
|
+
return { name, status: 'unknown', errorCode: 'blocked_by_network_unreachable' };
|
|
227
|
+
}
|
|
228
|
+
/** Unknown because the check itself is not wired yet. */
|
|
229
|
+
function notImplemented(name) {
|
|
230
|
+
return { name, status: 'unknown', errorCode: 'not_implemented' };
|
|
231
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Canonical Filecoin storage URI helpers.
|
|
3
|
+
*
|
|
4
|
+
* The plan pins the URI shape at `filecoin://piece/<pieceCid>` —
|
|
5
|
+
* PieceCID-centered identity per the design doc's URI Contract
|
|
6
|
+
* section. No query string, no fragment, no compatibility shim
|
|
7
|
+
* for legacy `ipfs://` rows.
|
|
8
|
+
*
|
|
9
|
+
* Phase 3 hardening: both helpers validate the PieceCID portion
|
|
10
|
+
* using the LIVE Synapse SDK parser (`asPieceCID` from
|
|
11
|
+
* `@filoz/synapse-core/piece`, wrapped in `./piece-cid.js`). A
|
|
12
|
+
* PieceCID that does not round-trip through the SDK's
|
|
13
|
+
* codec-aware parser (CIDv1, raw codec 0x55, multihash 0x1011)
|
|
14
|
+
* is rejected here, BEFORE the URI ever flows to head/get/delete
|
|
15
|
+
* or to the sidecar persister — eliminating the class of bug
|
|
16
|
+
* where a regex-valid-but-codec-invalid CID would be persisted
|
|
17
|
+
* and then fail downstream with a vendor-shaped error. The
|
|
18
|
+
* shared structural regex (`filecoin-cid-validation.ts`) is NOT
|
|
19
|
+
* used here; it lives on the eager-import path and is the
|
|
20
|
+
* narrower belt-and-suspenders gate for the public projection.
|
|
21
|
+
*
|
|
22
|
+
* Errors are typed `FilecoinProviderError` with sanitized codes:
|
|
23
|
+
*
|
|
24
|
+
* - `invalid_uri` — wrong scheme/host/shape (extra segments,
|
|
25
|
+
* missing piece host, query, fragment, non-string input).
|
|
26
|
+
* - `invalid_piece_cid` — shape OK but the trailing CID is
|
|
27
|
+
* not a valid PieceCIDv2 per the SDK parser.
|
|
28
|
+
*
|
|
29
|
+
* Callers never see a raw `URL` parser stack or vendor-shaped
|
|
30
|
+
* error.
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* Format a PieceCID into the canonical AtomicMemory storage URI.
|
|
34
|
+
* Throws `invalid_piece_cid` when the input is not a valid
|
|
35
|
+
* PieceCIDv2 (per the live Synapse SDK parser); throws
|
|
36
|
+
* `invalid_uri` when the input is empty or contains characters
|
|
37
|
+
* that aren't URI-safe. The returned URI carries the SDK's
|
|
38
|
+
* canonical string form of the PieceCID — non-canonical inputs
|
|
39
|
+
* either fail parsing or are normalized here.
|
|
40
|
+
*/
|
|
41
|
+
export declare function formatPieceUri(pieceCid: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Parse a `filecoin://piece/<pieceCid>` URI and return the
|
|
44
|
+
* PieceCID in the SDK's canonical string form. Throws
|
|
45
|
+
* `invalid_uri` on a wrong scheme/host/shape; throws
|
|
46
|
+
* `invalid_piece_cid` when the URI shape is correct but the
|
|
47
|
+
* trailing CID is not a valid PieceCIDv2 per the SDK parser.
|
|
48
|
+
*/
|
|
49
|
+
export declare function parsePieceUri(uri: string): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Canonical Filecoin storage URI helpers.
|
|
3
|
+
*
|
|
4
|
+
* The plan pins the URI shape at `filecoin://piece/<pieceCid>` —
|
|
5
|
+
* PieceCID-centered identity per the design doc's URI Contract
|
|
6
|
+
* section. No query string, no fragment, no compatibility shim
|
|
7
|
+
* for legacy `ipfs://` rows.
|
|
8
|
+
*
|
|
9
|
+
* Phase 3 hardening: both helpers validate the PieceCID portion
|
|
10
|
+
* using the LIVE Synapse SDK parser (`asPieceCID` from
|
|
11
|
+
* `@filoz/synapse-core/piece`, wrapped in `./piece-cid.js`). A
|
|
12
|
+
* PieceCID that does not round-trip through the SDK's
|
|
13
|
+
* codec-aware parser (CIDv1, raw codec 0x55, multihash 0x1011)
|
|
14
|
+
* is rejected here, BEFORE the URI ever flows to head/get/delete
|
|
15
|
+
* or to the sidecar persister — eliminating the class of bug
|
|
16
|
+
* where a regex-valid-but-codec-invalid CID would be persisted
|
|
17
|
+
* and then fail downstream with a vendor-shaped error. The
|
|
18
|
+
* shared structural regex (`filecoin-cid-validation.ts`) is NOT
|
|
19
|
+
* used here; it lives on the eager-import path and is the
|
|
20
|
+
* narrower belt-and-suspenders gate for the public projection.
|
|
21
|
+
*
|
|
22
|
+
* Errors are typed `FilecoinProviderError` with sanitized codes:
|
|
23
|
+
*
|
|
24
|
+
* - `invalid_uri` — wrong scheme/host/shape (extra segments,
|
|
25
|
+
* missing piece host, query, fragment, non-string input).
|
|
26
|
+
* - `invalid_piece_cid` — shape OK but the trailing CID is
|
|
27
|
+
* not a valid PieceCIDv2 per the SDK parser.
|
|
28
|
+
*
|
|
29
|
+
* Callers never see a raw `URL` parser stack or vendor-shaped
|
|
30
|
+
* error.
|
|
31
|
+
*/
|
|
32
|
+
import { FilecoinProviderError } from './errors.js';
|
|
33
|
+
import { requirePieceCid } from './piece-cid.js';
|
|
34
|
+
const FILECOIN_URI_SCHEME = 'filecoin:';
|
|
35
|
+
const FILECOIN_URI_PIECE_HOST = 'piece';
|
|
36
|
+
const FILECOIN_URI_PREFIX = `${FILECOIN_URI_SCHEME}//${FILECOIN_URI_PIECE_HOST}/`;
|
|
37
|
+
/**
|
|
38
|
+
* Format a PieceCID into the canonical AtomicMemory storage URI.
|
|
39
|
+
* Throws `invalid_piece_cid` when the input is not a valid
|
|
40
|
+
* PieceCIDv2 (per the live Synapse SDK parser); throws
|
|
41
|
+
* `invalid_uri` when the input is empty or contains characters
|
|
42
|
+
* that aren't URI-safe. The returned URI carries the SDK's
|
|
43
|
+
* canonical string form of the PieceCID — non-canonical inputs
|
|
44
|
+
* either fail parsing or are normalized here.
|
|
45
|
+
*/
|
|
46
|
+
export function formatPieceUri(pieceCid) {
|
|
47
|
+
const trimmed = pieceCid.trim();
|
|
48
|
+
if (trimmed.length === 0) {
|
|
49
|
+
throw new FilecoinProviderError('invalid_uri', 'Cannot format Filecoin URI: PieceCID is empty.');
|
|
50
|
+
}
|
|
51
|
+
if (/\s/.test(trimmed) || /[/?#]/.test(trimmed)) {
|
|
52
|
+
throw new FilecoinProviderError('invalid_uri', "PieceCID contains characters that are not URI-safe (whitespace or '/?#').");
|
|
53
|
+
}
|
|
54
|
+
// `requirePieceCid` runs the SDK's `asPieceCID` parser and
|
|
55
|
+
// returns the canonical string form. The error message is
|
|
56
|
+
// sanitized (no value echo) — malformed CIDs may encode
|
|
57
|
+
// adversarial bytes worth keeping out of log streams. The
|
|
58
|
+
// closed-set `errorCode` is the diagnostic surface.
|
|
59
|
+
const canonical = requirePieceCid(trimmed, 'PieceCID input');
|
|
60
|
+
return `${FILECOIN_URI_PREFIX}${canonical}`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse a `filecoin://piece/<pieceCid>` URI and return the
|
|
64
|
+
* PieceCID in the SDK's canonical string form. Throws
|
|
65
|
+
* `invalid_uri` on a wrong scheme/host/shape; throws
|
|
66
|
+
* `invalid_piece_cid` when the URI shape is correct but the
|
|
67
|
+
* trailing CID is not a valid PieceCIDv2 per the SDK parser.
|
|
68
|
+
*/
|
|
69
|
+
export function parsePieceUri(uri) {
|
|
70
|
+
if (typeof uri !== 'string' || uri.length === 0) {
|
|
71
|
+
throw new FilecoinProviderError('invalid_uri', 'Filecoin storage URI is missing or not a string.');
|
|
72
|
+
}
|
|
73
|
+
if (!uri.startsWith(FILECOIN_URI_PREFIX)) {
|
|
74
|
+
throw new FilecoinProviderError('invalid_uri', `Filecoin storage URI must start with '${FILECOIN_URI_PREFIX}'.`);
|
|
75
|
+
}
|
|
76
|
+
const remainder = uri.slice(FILECOIN_URI_PREFIX.length);
|
|
77
|
+
if (remainder.length === 0) {
|
|
78
|
+
throw new FilecoinProviderError('invalid_uri', `Filecoin storage URI '${FILECOIN_URI_PREFIX}' has no PieceCID.`);
|
|
79
|
+
}
|
|
80
|
+
if (remainder.includes('/') || remainder.includes('?') || remainder.includes('#')) {
|
|
81
|
+
throw new FilecoinProviderError('invalid_uri', "Filecoin storage URI must not contain extra segments, query strings, or fragments.");
|
|
82
|
+
}
|
|
83
|
+
return requirePieceCid(remainder, 'storage URI');
|
|
84
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Bounded-lifecycle + body-reading helpers for the
|
|
3
|
+
* verified-fetch retriever.
|
|
4
|
+
*
|
|
5
|
+
* Lifted out of `verified-fetch-retriever.ts` so the retriever
|
|
6
|
+
* file stays focused on the `FilecoinRetriever` implementation
|
|
7
|
+
* and this file owns the (subtle) timer-lifetime + race-loser
|
|
8
|
+
* contracts. The retriever wires these helpers together; the
|
|
9
|
+
* helpers do not import the retriever or any optional vendor
|
|
10
|
+
* package. Source-build-safety invariant
|
|
11
|
+
* (`filecoin-pin-lazy-boundary.test.ts`) requires zero static
|
|
12
|
+
* imports of `@helia/verified-fetch` / `@helia/*` etc. from
|
|
13
|
+
* this file.
|
|
14
|
+
*
|
|
15
|
+
* Contract summary:
|
|
16
|
+
*
|
|
17
|
+
* - `startLifecycle(timeoutMs)` builds an `AbortController` +
|
|
18
|
+
* a `setTimeout` cleared by `cancel()`. The sentinel
|
|
19
|
+
* promise rejects with `verified_fetch_timeout` on abort.
|
|
20
|
+
* - `runBoundedRetrieval` wraps fetch + classify + body-read
|
|
21
|
+
* in ONE `Promise.race` against the timeout sentinel.
|
|
22
|
+
* - `readBoundedBody` synchronously short-circuits when
|
|
23
|
+
* `signal.aborted` is already true (race-loser path) so a
|
|
24
|
+
* late-resolving fetch cannot leak a hung `reader.read()`.
|
|
25
|
+
* - `requireParsedCid` re-parses through `CID.parse`; an
|
|
26
|
+
* attacker-controlled `{ toString: () => 'https://attacker' }`
|
|
27
|
+
* is rejected.
|
|
28
|
+
* - `mapVerifiedFetchFailure` collapses any non-typed throw
|
|
29
|
+
* into the closed `verified_fetch_*` error-code set.
|
|
30
|
+
*/
|
|
31
|
+
import { FilecoinProviderError } from './errors.js';
|
|
32
|
+
import type { MinimalVerifiedFetch } from './verified-fetch-vendor.js';
|
|
33
|
+
/**
|
|
34
|
+
* Defence-in-depth runtime guard. The TS signature already
|
|
35
|
+
* requires a `CID`, but a JS caller bypassing the types must
|
|
36
|
+
* still be rejected. Critically, "looks like an object with a
|
|
37
|
+
* `toString()`" is NOT sufficient — an attacker-controlled
|
|
38
|
+
* `{ toString: () => 'https://attacker.example.com' }` would
|
|
39
|
+
* otherwise let an `ipfs://https://...` URL escape into
|
|
40
|
+
* verified-fetch. We re-parse the candidate's string form
|
|
41
|
+
* through `multiformats/cid.CID.parse`, which only accepts a
|
|
42
|
+
* real CID multibase string. Returns the canonical multibase
|
|
43
|
+
* form for the caller to consume.
|
|
44
|
+
*/
|
|
45
|
+
export declare function requireParsedCid(value: unknown): string;
|
|
46
|
+
export interface RetrievalLifecycle {
|
|
47
|
+
readonly aborter: AbortController | null;
|
|
48
|
+
readonly timeoutRejection: Promise<never> | null;
|
|
49
|
+
cancel(): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build the timeout + abort handle for a single retrieval. A
|
|
53
|
+
* non-null `aborter` is created only when `timeoutMs > 0`. The
|
|
54
|
+
* sentinel promise rejects with `verified_fetch_timeout` when
|
|
55
|
+
* the controller fires. `cancel()` clears the underlying timer
|
|
56
|
+
* on the success path so we don't leak a pending `setTimeout`
|
|
57
|
+
* past `get`'s lifetime.
|
|
58
|
+
*/
|
|
59
|
+
export declare function startLifecycle(timeoutMs: number | undefined): RetrievalLifecycle;
|
|
60
|
+
/**
|
|
61
|
+
* Run the entire fetch + classify + bounded-body-read sequence
|
|
62
|
+
* inside ONE `Promise.race` against the timeout sentinel. Race
|
|
63
|
+
* coverage extends past the initial fetch into body consumption
|
|
64
|
+
* so a vendor whose `reader.read()` never settles still cannot
|
|
65
|
+
* outlast `timeoutMs`. The signal is also forwarded into the
|
|
66
|
+
* body reader so a real Web-Streams implementation cancels its
|
|
67
|
+
* pending read on abort — the race is the deterministic
|
|
68
|
+
* back-stop for mocks / vendors that do not.
|
|
69
|
+
*/
|
|
70
|
+
export declare function runBoundedRetrieval(args: {
|
|
71
|
+
readonly fetch: MinimalVerifiedFetch;
|
|
72
|
+
readonly url: string;
|
|
73
|
+
readonly maxBytes: number;
|
|
74
|
+
readonly signal: AbortSignal | undefined;
|
|
75
|
+
readonly timeoutRejection: Promise<never> | null;
|
|
76
|
+
}): Promise<Buffer>;
|
|
77
|
+
export declare function mapVerifiedFetchFailure(err: unknown, aborter: AbortController | null, timeoutMs: number | undefined): FilecoinProviderError;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Bounded-lifecycle + body-reading helpers for the
|
|
3
|
+
* verified-fetch retriever.
|
|
4
|
+
*
|
|
5
|
+
* Lifted out of `verified-fetch-retriever.ts` so the retriever
|
|
6
|
+
* file stays focused on the `FilecoinRetriever` implementation
|
|
7
|
+
* and this file owns the (subtle) timer-lifetime + race-loser
|
|
8
|
+
* contracts. The retriever wires these helpers together; the
|
|
9
|
+
* helpers do not import the retriever or any optional vendor
|
|
10
|
+
* package. Source-build-safety invariant
|
|
11
|
+
* (`filecoin-pin-lazy-boundary.test.ts`) requires zero static
|
|
12
|
+
* imports of `@helia/verified-fetch` / `@helia/*` etc. from
|
|
13
|
+
* this file.
|
|
14
|
+
*
|
|
15
|
+
* Contract summary:
|
|
16
|
+
*
|
|
17
|
+
* - `startLifecycle(timeoutMs)` builds an `AbortController` +
|
|
18
|
+
* a `setTimeout` cleared by `cancel()`. The sentinel
|
|
19
|
+
* promise rejects with `verified_fetch_timeout` on abort.
|
|
20
|
+
* - `runBoundedRetrieval` wraps fetch + classify + body-read
|
|
21
|
+
* in ONE `Promise.race` against the timeout sentinel.
|
|
22
|
+
* - `readBoundedBody` synchronously short-circuits when
|
|
23
|
+
* `signal.aborted` is already true (race-loser path) so a
|
|
24
|
+
* late-resolving fetch cannot leak a hung `reader.read()`.
|
|
25
|
+
* - `requireParsedCid` re-parses through `CID.parse`; an
|
|
26
|
+
* attacker-controlled `{ toString: () => 'https://attacker' }`
|
|
27
|
+
* is rejected.
|
|
28
|
+
* - `mapVerifiedFetchFailure` collapses any non-typed throw
|
|
29
|
+
* into the closed `verified_fetch_*` error-code set.
|
|
30
|
+
*/
|
|
31
|
+
import { CID } from 'multiformats/cid';
|
|
32
|
+
import { FilecoinProviderError } from './errors.js';
|
|
33
|
+
/**
|
|
34
|
+
* Defence-in-depth runtime guard. The TS signature already
|
|
35
|
+
* requires a `CID`, but a JS caller bypassing the types must
|
|
36
|
+
* still be rejected. Critically, "looks like an object with a
|
|
37
|
+
* `toString()`" is NOT sufficient — an attacker-controlled
|
|
38
|
+
* `{ toString: () => 'https://attacker.example.com' }` would
|
|
39
|
+
* otherwise let an `ipfs://https://...` URL escape into
|
|
40
|
+
* verified-fetch. We re-parse the candidate's string form
|
|
41
|
+
* through `multiformats/cid.CID.parse`, which only accepts a
|
|
42
|
+
* real CID multibase string. Returns the canonical multibase
|
|
43
|
+
* form for the caller to consume.
|
|
44
|
+
*/
|
|
45
|
+
export function requireParsedCid(value) {
|
|
46
|
+
const shapedLikeCid = typeof value === 'object' &&
|
|
47
|
+
value !== null &&
|
|
48
|
+
typeof value.toString === 'function';
|
|
49
|
+
if (!shapedLikeCid)
|
|
50
|
+
throw invalidCidError();
|
|
51
|
+
const candidate = value.toString();
|
|
52
|
+
if (typeof candidate !== 'string')
|
|
53
|
+
throw invalidCidError();
|
|
54
|
+
try {
|
|
55
|
+
return CID.parse(candidate).toString();
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw invalidCidError();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function invalidCidError() {
|
|
62
|
+
return new FilecoinProviderError('verified_fetch_invalid_cid', 'Verified-fetch retriever requires a parsed CID instance, not a URL or arbitrary string.');
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Build the timeout + abort handle for a single retrieval. A
|
|
66
|
+
* non-null `aborter` is created only when `timeoutMs > 0`. The
|
|
67
|
+
* sentinel promise rejects with `verified_fetch_timeout` when
|
|
68
|
+
* the controller fires. `cancel()` clears the underlying timer
|
|
69
|
+
* on the success path so we don't leak a pending `setTimeout`
|
|
70
|
+
* past `get`'s lifetime.
|
|
71
|
+
*/
|
|
72
|
+
export function startLifecycle(timeoutMs) {
|
|
73
|
+
if (timeoutMs === undefined || timeoutMs <= 0) {
|
|
74
|
+
return { aborter: null, timeoutRejection: null, cancel: () => undefined };
|
|
75
|
+
}
|
|
76
|
+
const aborter = new AbortController();
|
|
77
|
+
const timer = setTimeout(() => aborter.abort(), timeoutMs);
|
|
78
|
+
timer.unref?.();
|
|
79
|
+
const timeoutRejection = new Promise((_, reject) => {
|
|
80
|
+
aborter.signal.addEventListener('abort', () => {
|
|
81
|
+
reject(new FilecoinProviderError('verified_fetch_timeout', `Verified-fetch retrieval aborted after ${timeoutMs} ms.`));
|
|
82
|
+
}, { once: true });
|
|
83
|
+
});
|
|
84
|
+
timeoutRejection.catch(() => undefined);
|
|
85
|
+
return {
|
|
86
|
+
aborter,
|
|
87
|
+
timeoutRejection,
|
|
88
|
+
cancel() { clearTimeout(timer); },
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Run the entire fetch + classify + bounded-body-read sequence
|
|
93
|
+
* inside ONE `Promise.race` against the timeout sentinel. Race
|
|
94
|
+
* coverage extends past the initial fetch into body consumption
|
|
95
|
+
* so a vendor whose `reader.read()` never settles still cannot
|
|
96
|
+
* outlast `timeoutMs`. The signal is also forwarded into the
|
|
97
|
+
* body reader so a real Web-Streams implementation cancels its
|
|
98
|
+
* pending read on abort — the race is the deterministic
|
|
99
|
+
* back-stop for mocks / vendors that do not.
|
|
100
|
+
*/
|
|
101
|
+
export async function runBoundedRetrieval(args) {
|
|
102
|
+
const operation = (async () => {
|
|
103
|
+
const response = await args.fetch(args.url, args.signal !== undefined ? { signal: args.signal } : undefined);
|
|
104
|
+
classifyResponse(response);
|
|
105
|
+
return readBoundedBody(response, args.maxBytes, args.signal);
|
|
106
|
+
})();
|
|
107
|
+
if (args.timeoutRejection !== null) {
|
|
108
|
+
// Attach a no-op tail to the operation promise so its
|
|
109
|
+
// race-loser rejection (e.g. the `verified_fetch_timeout`
|
|
110
|
+
// `readBoundedBody` throws when it sees an already-aborted
|
|
111
|
+
// signal) does NOT surface as `unhandledRejection`. Node's
|
|
112
|
+
// tracker is satisfied; the rejection has nowhere else to
|
|
113
|
+
// go because the outer race already chose the timeout.
|
|
114
|
+
operation.catch(() => undefined);
|
|
115
|
+
return Promise.race([operation, args.timeoutRejection]);
|
|
116
|
+
}
|
|
117
|
+
return operation;
|
|
118
|
+
}
|
|
119
|
+
function classifyResponse(response) {
|
|
120
|
+
if (response.status === 404) {
|
|
121
|
+
throw new FilecoinProviderError('verified_fetch_not_found', 'Verified-fetch retrieval returned 404 — content not available on the IPFS network.');
|
|
122
|
+
}
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
throw new FilecoinProviderError('verified_fetch_failed', `Verified-fetch retrieval failed with status ${response.status}.`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export function mapVerifiedFetchFailure(err, aborter, timeoutMs) {
|
|
128
|
+
if (err instanceof FilecoinProviderError)
|
|
129
|
+
return err;
|
|
130
|
+
if (aborter?.signal.aborted) {
|
|
131
|
+
return new FilecoinProviderError('verified_fetch_timeout', `Verified-fetch retrieval aborted after ${timeoutMs} ms.`);
|
|
132
|
+
}
|
|
133
|
+
return new FilecoinProviderError('verified_fetch_failed', 'Verified-fetch retrieval failed.');
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Read the response body, enforcing a size cap that protects
|
|
137
|
+
* against unbounded retrieval. Synchronous race-loser exit if
|
|
138
|
+
* `signal.aborted` is already true (the outer race has already
|
|
139
|
+
* chosen the timeout sentinel) — cancels the reader, throws
|
|
140
|
+
* `verified_fetch_timeout`. Otherwise dispatches to one of the
|
|
141
|
+
* two streaming/buffered readers.
|
|
142
|
+
*/
|
|
143
|
+
async function readBoundedBody(response, maxBytes, signal) {
|
|
144
|
+
const reader = response.body?.getReader();
|
|
145
|
+
if (signal?.aborted)
|
|
146
|
+
await bailAlreadyAborted(reader);
|
|
147
|
+
if (reader === undefined)
|
|
148
|
+
return readBufferedBody(response, maxBytes);
|
|
149
|
+
return readStreamingBody(reader, maxBytes, signal);
|
|
150
|
+
}
|
|
151
|
+
async function bailAlreadyAborted(reader) {
|
|
152
|
+
if (reader !== undefined) {
|
|
153
|
+
try {
|
|
154
|
+
await reader.cancel();
|
|
155
|
+
}
|
|
156
|
+
catch { /* tear-down only */ }
|
|
157
|
+
}
|
|
158
|
+
throw new FilecoinProviderError('verified_fetch_timeout', 'Verified-fetch retrieval aborted before body read began.');
|
|
159
|
+
}
|
|
160
|
+
async function readBufferedBody(response, maxBytes) {
|
|
161
|
+
const buf = Buffer.from(await response.arrayBuffer());
|
|
162
|
+
if (buf.length > maxBytes) {
|
|
163
|
+
throw new FilecoinProviderError('verified_fetch_body_too_large', `Verified-fetch body exceeded the ${maxBytes}-byte ceiling.`);
|
|
164
|
+
}
|
|
165
|
+
return buf;
|
|
166
|
+
}
|
|
167
|
+
async function readStreamingBody(reader, maxBytes, signal) {
|
|
168
|
+
const onAbort = () => {
|
|
169
|
+
void reader.cancel().catch(() => undefined);
|
|
170
|
+
};
|
|
171
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
172
|
+
const chunks = [];
|
|
173
|
+
let total = 0;
|
|
174
|
+
try {
|
|
175
|
+
while (true) {
|
|
176
|
+
const { done, value } = await reader.read();
|
|
177
|
+
if (done)
|
|
178
|
+
break;
|
|
179
|
+
if (value !== undefined) {
|
|
180
|
+
total += value.byteLength;
|
|
181
|
+
if (total > maxBytes) {
|
|
182
|
+
throw new FilecoinProviderError('verified_fetch_body_too_large', `Verified-fetch body exceeded the ${maxBytes}-byte ceiling.`);
|
|
183
|
+
}
|
|
184
|
+
chunks.push(value);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
signal?.removeEventListener('abort', onAbort);
|
|
190
|
+
try {
|
|
191
|
+
await reader.cancel();
|
|
192
|
+
}
|
|
193
|
+
catch { /* tear-down only */ }
|
|
194
|
+
}
|
|
195
|
+
return Buffer.concat(chunks);
|
|
196
|
+
}
|