@ryanstark24/sfgraph-core 1.2.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyze/apex-platform.d.ts +23 -0
- package/dist/analyze/apex-platform.d.ts.map +1 -0
- package/dist/analyze/apex-platform.js +112 -0
- package/dist/analyze/apex-platform.js.map +1 -0
- package/dist/analyze/audit-graph.d.ts +51 -3
- package/dist/analyze/audit-graph.d.ts.map +1 -1
- package/dist/analyze/audit-graph.js +382 -14
- package/dist/analyze/audit-graph.js.map +1 -1
- package/dist/analyze/component-scope.d.ts +82 -0
- package/dist/analyze/component-scope.d.ts.map +1 -0
- package/dist/analyze/component-scope.js +207 -0
- package/dist/analyze/component-scope.js.map +1 -0
- package/dist/analyze/containment.d.ts +91 -0
- package/dist/analyze/containment.d.ts.map +1 -0
- package/dist/analyze/containment.js +175 -0
- package/dist/analyze/containment.js.map +1 -0
- package/dist/analyze/cross-org.d.ts +35 -0
- package/dist/analyze/cross-org.d.ts.map +1 -1
- package/dist/analyze/cross-org.js +102 -3
- package/dist/analyze/cross-org.js.map +1 -1
- package/dist/analyze/dead-code.d.ts +99 -3
- package/dist/analyze/dead-code.d.ts.map +1 -1
- package/dist/analyze/dead-code.js +282 -10
- package/dist/analyze/dead-code.js.map +1 -1
- package/dist/analyze/dependencies.d.ts +21 -2
- package/dist/analyze/dependencies.d.ts.map +1 -1
- package/dist/analyze/dependencies.js +102 -12
- package/dist/analyze/dependencies.js.map +1 -1
- package/dist/analyze/dependents.d.ts +116 -1
- package/dist/analyze/dependents.d.ts.map +1 -1
- package/dist/analyze/dependents.js +285 -13
- package/dist/analyze/dependents.js.map +1 -1
- package/dist/analyze/deployment-manifest/generate.d.ts +24 -0
- package/dist/analyze/deployment-manifest/generate.d.ts.map +1 -1
- package/dist/analyze/deployment-manifest/generate.js +40 -12
- package/dist/analyze/deployment-manifest/generate.js.map +1 -1
- package/dist/analyze/deployment-manifest/member-name-formatters.d.ts.map +1 -1
- package/dist/analyze/deployment-manifest/member-name-formatters.js +1 -0
- package/dist/analyze/deployment-manifest/member-name-formatters.js.map +1 -1
- package/dist/analyze/deployment-manifest/member-types.d.ts.map +1 -1
- package/dist/analyze/deployment-manifest/member-types.js +2 -0
- package/dist/analyze/deployment-manifest/member-types.js.map +1 -1
- package/dist/analyze/diff-seeds.d.ts +33 -0
- package/dist/analyze/diff-seeds.d.ts.map +1 -0
- package/dist/analyze/diff-seeds.js +299 -0
- package/dist/analyze/diff-seeds.js.map +1 -0
- package/dist/analyze/edge-filters.d.ts +62 -0
- package/dist/analyze/edge-filters.d.ts.map +1 -0
- package/dist/analyze/edge-filters.js +127 -0
- package/dist/analyze/edge-filters.js.map +1 -0
- package/dist/analyze/field-scope.d.ts +25 -0
- package/dist/analyze/field-scope.d.ts.map +1 -0
- package/dist/analyze/field-scope.js +94 -0
- package/dist/analyze/field-scope.js.map +1 -0
- package/dist/analyze/find-nodes.d.ts +48 -12
- package/dist/analyze/find-nodes.d.ts.map +1 -1
- package/dist/analyze/find-nodes.js +323 -12
- package/dist/analyze/find-nodes.js.map +1 -1
- package/dist/analyze/findings.d.ts +1 -1
- package/dist/analyze/findings.d.ts.map +1 -1
- package/dist/analyze/findings.js +15 -3
- package/dist/analyze/findings.js.map +1 -1
- package/dist/analyze/git-diff.d.ts +27 -1
- package/dist/analyze/git-diff.d.ts.map +1 -1
- package/dist/analyze/git-diff.js +198 -26
- package/dist/analyze/git-diff.js.map +1 -1
- package/dist/analyze/governor.d.ts +25 -4
- package/dist/analyze/governor.d.ts.map +1 -1
- package/dist/analyze/governor.js +82 -18
- package/dist/analyze/governor.js.map +1 -1
- package/dist/analyze/index.d.ts +6 -0
- package/dist/analyze/index.d.ts.map +1 -1
- package/dist/analyze/index.js +6 -0
- package/dist/analyze/index.js.map +1 -1
- package/dist/analyze/path-to-qname.d.ts +9 -0
- package/dist/analyze/path-to-qname.d.ts.map +1 -1
- package/dist/analyze/path-to-qname.js +58 -15
- package/dist/analyze/path-to-qname.js.map +1 -1
- package/dist/analyze/populate.d.ts +40 -0
- package/dist/analyze/populate.d.ts.map +1 -1
- package/dist/analyze/populate.js +203 -58
- package/dist/analyze/populate.js.map +1 -1
- package/dist/analyze/pseudo-endpoints.d.ts +67 -0
- package/dist/analyze/pseudo-endpoints.d.ts.map +1 -0
- package/dist/analyze/pseudo-endpoints.js +78 -0
- package/dist/analyze/pseudo-endpoints.js.map +1 -0
- package/dist/analyze/security.d.ts +17 -0
- package/dist/analyze/security.d.ts.map +1 -1
- package/dist/analyze/security.js +103 -18
- package/dist/analyze/security.js.map +1 -1
- package/dist/analyze/test-coverage.d.ts +48 -0
- package/dist/analyze/test-coverage.d.ts.map +1 -1
- package/dist/analyze/test-coverage.js +72 -1
- package/dist/analyze/test-coverage.js.map +1 -1
- package/dist/analyze/wip-changed-files.d.ts +88 -0
- package/dist/analyze/wip-changed-files.d.ts.map +1 -0
- package/dist/analyze/wip-changed-files.js +422 -0
- package/dist/analyze/wip-changed-files.js.map +1 -0
- package/dist/analyze/wip-impact.d.ts +59 -0
- package/dist/analyze/wip-impact.d.ts.map +1 -1
- package/dist/analyze/wip-impact.js +199 -116
- package/dist/analyze/wip-impact.js.map +1 -1
- package/dist/domain/apex-platform.d.ts +10 -0
- package/dist/domain/apex-platform.d.ts.map +1 -0
- package/dist/domain/apex-platform.js +231 -0
- package/dist/domain/apex-platform.js.map +1 -0
- package/dist/domain/index.d.ts +2 -0
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +2 -0
- package/dist/domain/index.js.map +1 -1
- package/dist/domain/metadata-category.d.ts +1 -0
- package/dist/domain/metadata-category.d.ts.map +1 -1
- package/dist/domain/metadata-category.js +1 -0
- package/dist/domain/metadata-category.js.map +1 -1
- package/dist/domain/rel-types.d.ts +7 -0
- package/dist/domain/rel-types.d.ts.map +1 -1
- package/dist/domain/rel-types.js +7 -0
- package/dist/domain/rel-types.js.map +1 -1
- package/dist/domain/standard-sobjects.d.ts +20 -0
- package/dist/domain/standard-sobjects.d.ts.map +1 -0
- package/dist/domain/standard-sobjects.js +183 -0
- package/dist/domain/standard-sobjects.js.map +1 -0
- package/dist/embedding/cache.d.ts +41 -0
- package/dist/embedding/cache.d.ts.map +1 -0
- package/dist/embedding/cache.js +69 -0
- package/dist/embedding/cache.js.map +1 -0
- package/dist/embedding/embed.d.ts +59 -0
- package/dist/embedding/embed.d.ts.map +1 -1
- package/dist/embedding/embed.js +207 -29
- package/dist/embedding/embed.js.map +1 -1
- package/dist/embedding/index.d.ts +7 -0
- package/dist/embedding/index.d.ts.map +1 -1
- package/dist/embedding/index.js +4 -0
- package/dist/embedding/index.js.map +1 -1
- package/dist/embedding/pool.d.ts +66 -6
- package/dist/embedding/pool.d.ts.map +1 -1
- package/dist/embedding/pool.js +156 -6
- package/dist/embedding/pool.js.map +1 -1
- package/dist/embedding/queue.d.ts +166 -9
- package/dist/embedding/queue.d.ts.map +1 -1
- package/dist/embedding/queue.js +397 -39
- package/dist/embedding/queue.js.map +1 -1
- package/dist/embedding/tokenize.d.ts +18 -0
- package/dist/embedding/tokenize.d.ts.map +1 -0
- package/dist/embedding/tokenize.js +43 -0
- package/dist/embedding/tokenize.js.map +1 -0
- package/dist/embedding/worker.d.ts +0 -5
- package/dist/embedding/worker.d.ts.map +1 -1
- package/dist/embedding/worker.js +27 -4
- package/dist/embedding/worker.js.map +1 -1
- package/dist/extractors/filesystem/index.d.ts +21 -1
- package/dist/extractors/filesystem/index.d.ts.map +1 -1
- package/dist/extractors/filesystem/index.js +195 -38
- package/dist/extractors/filesystem/index.js.map +1 -1
- package/dist/extractors/filesystem/vlocity-datapacks.d.ts +27 -0
- package/dist/extractors/filesystem/vlocity-datapacks.d.ts.map +1 -0
- package/dist/extractors/filesystem/vlocity-datapacks.js +201 -0
- package/dist/extractors/filesystem/vlocity-datapacks.js.map +1 -0
- package/dist/extractors/interfaces/metadata-source.d.ts +40 -0
- package/dist/extractors/interfaces/metadata-source.d.ts.map +1 -1
- package/dist/extractors/live-org/bulk-retrieve.d.ts +206 -1
- package/dist/extractors/live-org/bulk-retrieve.d.ts.map +1 -1
- package/dist/extractors/live-org/bulk-retrieve.js +706 -94
- package/dist/extractors/live-org/bulk-retrieve.js.map +1 -1
- package/dist/extractors/live-org/capabilities.d.ts +15 -0
- package/dist/extractors/live-org/capabilities.d.ts.map +1 -1
- package/dist/extractors/live-org/capabilities.js +54 -9
- package/dist/extractors/live-org/capabilities.js.map +1 -1
- package/dist/extractors/live-org/extractors/apex.d.ts +12 -2
- package/dist/extractors/live-org/extractors/apex.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/apex.js +171 -75
- package/dist/extractors/live-org/extractors/apex.js.map +1 -1
- package/dist/extractors/live-org/extractors/custom-settings.d.ts +4 -0
- package/dist/extractors/live-org/extractors/custom-settings.d.ts.map +1 -0
- package/dist/extractors/live-org/extractors/custom-settings.js +76 -0
- package/dist/extractors/live-org/extractors/custom-settings.js.map +1 -0
- package/dist/extractors/live-org/extractors/flow.d.ts +2 -1
- package/dist/extractors/live-org/extractors/flow.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/flow.js +12 -3
- package/dist/extractors/live-org/extractors/flow.js.map +1 -1
- package/dist/extractors/live-org/extractors/generic-metadata.d.ts +23 -3
- package/dist/extractors/live-org/extractors/generic-metadata.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/generic-metadata.js +110 -25
- package/dist/extractors/live-org/extractors/generic-metadata.js.map +1 -1
- package/dist/extractors/live-org/extractors/generic-sobject.js.map +1 -1
- package/dist/extractors/live-org/extractors/integration.d.ts +2 -1
- package/dist/extractors/live-org/extractors/integration.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/integration.js +14 -5
- package/dist/extractors/live-org/extractors/integration.js.map +1 -1
- package/dist/extractors/live-org/extractors/lwc.d.ts +2 -1
- package/dist/extractors/live-org/extractors/lwc.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/lwc.js +95 -47
- package/dist/extractors/live-org/extractors/lwc.js.map +1 -1
- package/dist/extractors/live-org/extractors/mcd-baseline.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/mcd-baseline.js +2 -4
- package/dist/extractors/live-org/extractors/mcd-baseline.js.map +1 -1
- package/dist/extractors/live-org/extractors/object.d.ts +2 -11
- package/dist/extractors/live-org/extractors/object.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/object.js +127 -226
- package/dist/extractors/live-org/extractors/object.js.map +1 -1
- package/dist/extractors/live-org/extractors/omnistudio-retrieve.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/omnistudio-retrieve.js.map +1 -1
- package/dist/extractors/live-org/extractors/omnistudio.d.ts +11 -1
- package/dist/extractors/live-org/extractors/omnistudio.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/omnistudio.js +104 -16
- package/dist/extractors/live-org/extractors/omnistudio.js.map +1 -1
- package/dist/extractors/live-org/extractors/security.d.ts +12 -1
- package/dist/extractors/live-org/extractors/security.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/security.js +29 -7
- package/dist/extractors/live-org/extractors/security.js.map +1 -1
- package/dist/extractors/live-org/rate-limit.d.ts +48 -16
- package/dist/extractors/live-org/rate-limit.d.ts.map +1 -1
- package/dist/extractors/live-org/rate-limit.js +235 -40
- package/dist/extractors/live-org/rate-limit.js.map +1 -1
- package/dist/extractors/live-org/retry.d.ts +136 -0
- package/dist/extractors/live-org/retry.d.ts.map +1 -0
- package/dist/extractors/live-org/retry.js +416 -0
- package/dist/extractors/live-org/retry.js.map +1 -0
- package/dist/extractors/live-org/vlocity/runner.d.ts +2 -1
- package/dist/extractors/live-org/vlocity/runner.d.ts.map +1 -1
- package/dist/extractors/live-org/vlocity/runner.js +124 -72
- package/dist/extractors/live-org/vlocity/runner.js.map +1 -1
- package/dist/extractors/vlocity-shared/row.d.ts +19 -0
- package/dist/extractors/vlocity-shared/row.d.ts.map +1 -0
- package/dist/extractors/vlocity-shared/row.js +69 -0
- package/dist/extractors/vlocity-shared/row.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ingest/delta.d.ts +70 -0
- package/dist/ingest/delta.d.ts.map +1 -0
- package/dist/ingest/delta.js +534 -0
- package/dist/ingest/delta.js.map +1 -0
- package/dist/ingest/detect-deletions-guard.d.ts +79 -0
- package/dist/ingest/detect-deletions-guard.d.ts.map +1 -0
- package/dist/ingest/detect-deletions-guard.js +122 -0
- package/dist/ingest/detect-deletions-guard.js.map +1 -0
- package/dist/ingest/index.d.ts +8 -1
- package/dist/ingest/index.d.ts.map +1 -1
- package/dist/ingest/index.js +4 -0
- package/dist/ingest/index.js.map +1 -1
- package/dist/ingest/live-ingest.d.ts +180 -0
- package/dist/ingest/live-ingest.d.ts.map +1 -1
- package/dist/ingest/live-ingest.js +1617 -625
- package/dist/ingest/live-ingest.js.map +1 -1
- package/dist/ingest/lock.d.ts +47 -0
- package/dist/ingest/lock.d.ts.map +1 -0
- package/dist/ingest/lock.js +222 -0
- package/dist/ingest/lock.js.map +1 -0
- package/dist/ingest/member-rows.d.ts +88 -0
- package/dist/ingest/member-rows.d.ts.map +1 -0
- package/dist/ingest/member-rows.js +152 -0
- package/dist/ingest/member-rows.js.map +1 -0
- package/dist/ingest/offline-org.d.ts +8 -0
- package/dist/ingest/offline-org.d.ts.map +1 -0
- package/dist/ingest/offline-org.js +41 -0
- package/dist/ingest/offline-org.js.map +1 -0
- package/dist/ingest/parse-member.d.ts +53 -0
- package/dist/ingest/parse-member.d.ts.map +1 -0
- package/dist/ingest/parse-member.js +276 -0
- package/dist/ingest/parse-member.js.map +1 -0
- package/dist/ingest/parse-pool.d.ts +139 -0
- package/dist/ingest/parse-pool.d.ts.map +1 -0
- package/dist/ingest/parse-pool.js +593 -0
- package/dist/ingest/parse-pool.js.map +1 -0
- package/dist/ingest/parse-worker.d.ts +3 -0
- package/dist/ingest/parse-worker.d.ts.map +1 -0
- package/dist/ingest/parse-worker.js +100 -0
- package/dist/ingest/parse-worker.js.map +1 -0
- package/dist/ingest/profile.d.ts +27 -0
- package/dist/ingest/profile.d.ts.map +1 -0
- package/dist/ingest/profile.js +48 -0
- package/dist/ingest/profile.js.map +1 -0
- package/dist/ingest/resolver-gates.d.ts +12 -0
- package/dist/ingest/resolver-gates.d.ts.map +1 -0
- package/dist/ingest/resolver-gates.js +53 -0
- package/dist/ingest/resolver-gates.js.map +1 -0
- package/dist/parsers/apex/arity-resolver.d.ts +16 -3
- package/dist/parsers/apex/arity-resolver.d.ts.map +1 -1
- package/dist/parsers/apex/arity-resolver.js +31 -2
- package/dist/parsers/apex/arity-resolver.js.map +1 -1
- package/dist/parsers/apex/ast-extractor.d.ts +4 -0
- package/dist/parsers/apex/ast-extractor.d.ts.map +1 -1
- package/dist/parsers/apex/ast-extractor.js +128 -29
- package/dist/parsers/apex/ast-extractor.js.map +1 -1
- package/dist/parsers/apex/class-refs.d.ts +78 -0
- package/dist/parsers/apex/class-refs.d.ts.map +1 -0
- package/dist/parsers/apex/class-refs.js +465 -0
- package/dist/parsers/apex/class-refs.js.map +1 -0
- package/dist/parsers/apex/class.d.ts +158 -0
- package/dist/parsers/apex/class.d.ts.map +1 -1
- package/dist/parsers/apex/class.js +1073 -172
- package/dist/parsers/apex/class.js.map +1 -1
- package/dist/parsers/apex/dynamic-soql.d.ts +52 -0
- package/dist/parsers/apex/dynamic-soql.d.ts.map +1 -0
- package/dist/parsers/apex/dynamic-soql.js +427 -0
- package/dist/parsers/apex/dynamic-soql.js.map +1 -0
- package/dist/parsers/apex/field-access.d.ts +65 -0
- package/dist/parsers/apex/field-access.d.ts.map +1 -0
- package/dist/parsers/apex/field-access.js +438 -0
- package/dist/parsers/apex/field-access.js.map +1 -0
- package/dist/parsers/apex/interface-ref-resolver.d.ts +32 -0
- package/dist/parsers/apex/interface-ref-resolver.d.ts.map +1 -0
- package/dist/parsers/apex/interface-ref-resolver.js +64 -0
- package/dist/parsers/apex/interface-ref-resolver.js.map +1 -0
- package/dist/parsers/apex/name-refs.d.ts +83 -0
- package/dist/parsers/apex/name-refs.d.ts.map +1 -0
- package/dist/parsers/apex/name-refs.js +465 -0
- package/dist/parsers/apex/name-refs.js.map +1 -0
- package/dist/parsers/apex/page-refs.d.ts +11 -0
- package/dist/parsers/apex/page-refs.d.ts.map +1 -0
- package/dist/parsers/apex/page-refs.js +34 -0
- package/dist/parsers/apex/page-refs.js.map +1 -0
- package/dist/parsers/apex/ref-resolver.d.ts +58 -0
- package/dist/parsers/apex/ref-resolver.d.ts.map +1 -0
- package/dist/parsers/apex/ref-resolver.js +348 -0
- package/dist/parsers/apex/ref-resolver.js.map +1 -0
- package/dist/parsers/apex/soql-fields.d.ts +75 -0
- package/dist/parsers/apex/soql-fields.d.ts.map +1 -0
- package/dist/parsers/apex/soql-fields.js +338 -0
- package/dist/parsers/apex/soql-fields.js.map +1 -0
- package/dist/parsers/apex/trigger.d.ts.map +1 -1
- package/dist/parsers/apex/trigger.js +100 -2
- package/dist/parsers/apex/trigger.js.map +1 -1
- package/dist/parsers/apex/vlocity-calls.d.ts +25 -0
- package/dist/parsers/apex/vlocity-calls.d.ts.map +1 -0
- package/dist/parsers/apex/vlocity-calls.js +225 -0
- package/dist/parsers/apex/vlocity-calls.js.map +1 -0
- package/dist/parsers/aura/bundle.d.ts +39 -0
- package/dist/parsers/aura/bundle.d.ts.map +1 -0
- package/dist/parsers/aura/bundle.js +269 -0
- package/dist/parsers/aura/bundle.js.map +1 -0
- package/dist/parsers/aura/embed-resolver.d.ts +17 -0
- package/dist/parsers/aura/embed-resolver.d.ts.map +1 -0
- package/dist/parsers/aura/embed-resolver.js +58 -0
- package/dist/parsers/aura/embed-resolver.js.map +1 -0
- package/dist/parsers/aura/index.d.ts +4 -0
- package/dist/parsers/aura/index.d.ts.map +1 -0
- package/dist/parsers/aura/index.js +6 -0
- package/dist/parsers/aura/index.js.map +1 -0
- package/dist/parsers/common.d.ts +9 -0
- package/dist/parsers/common.d.ts.map +1 -1
- package/dist/parsers/common.js +17 -0
- package/dist/parsers/common.js.map +1 -1
- package/dist/parsers/cross-flavor-resolver.js +8 -2
- package/dist/parsers/cross-flavor-resolver.js.map +1 -1
- package/dist/parsers/flow/invocable-resolver.d.ts.map +1 -1
- package/dist/parsers/flow/invocable-resolver.js +2 -0
- package/dist/parsers/flow/invocable-resolver.js.map +1 -1
- package/dist/parsers/flow/parser.d.ts +9 -0
- package/dist/parsers/flow/parser.d.ts.map +1 -1
- package/dist/parsers/flow/parser.js +327 -2
- package/dist/parsers/flow/parser.js.map +1 -1
- package/dist/parsers/flow/relationship-resolver.d.ts +34 -0
- package/dist/parsers/flow/relationship-resolver.d.ts.map +1 -0
- package/dist/parsers/flow/relationship-resolver.js +199 -0
- package/dist/parsers/flow/relationship-resolver.js.map +1 -0
- package/dist/parsers/generic/opaque-node-parser.d.ts +5 -1
- package/dist/parsers/generic/opaque-node-parser.d.ts.map +1 -1
- package/dist/parsers/generic/opaque-node-parser.js +37 -5
- package/dist/parsers/generic/opaque-node-parser.js.map +1 -1
- package/dist/parsers/generic/reflection-walker.d.ts +7 -0
- package/dist/parsers/generic/reflection-walker.d.ts.map +1 -1
- package/dist/parsers/generic/reflection-walker.js +38 -13
- package/dist/parsers/generic/reflection-walker.js.map +1 -1
- package/dist/parsers/hash-salts.d.ts +72 -0
- package/dist/parsers/hash-salts.d.ts.map +1 -0
- package/dist/parsers/hash-salts.js +91 -0
- package/dist/parsers/hash-salts.js.map +1 -0
- package/dist/parsers/index.d.ts +2 -0
- package/dist/parsers/index.d.ts.map +1 -1
- package/dist/parsers/index.js +2 -0
- package/dist/parsers/index.js.map +1 -1
- package/dist/parsers/lwc/bundle.d.ts +1 -0
- package/dist/parsers/lwc/bundle.d.ts.map +1 -1
- package/dist/parsers/lwc/bundle.js +37 -2
- package/dist/parsers/lwc/bundle.js.map +1 -1
- package/dist/parsers/lwc/field-key-resolver.d.ts +32 -0
- package/dist/parsers/lwc/field-key-resolver.d.ts.map +1 -0
- package/dist/parsers/lwc/field-key-resolver.js +92 -0
- package/dist/parsers/lwc/field-key-resolver.js.map +1 -0
- package/dist/parsers/lwc/html-visitor.d.ts +1 -1
- package/dist/parsers/lwc/html-visitor.d.ts.map +1 -1
- package/dist/parsers/lwc/html-visitor.js +81 -3
- package/dist/parsers/lwc/html-visitor.js.map +1 -1
- package/dist/parsers/lwc/js-visitor.d.ts +16 -0
- package/dist/parsers/lwc/js-visitor.d.ts.map +1 -1
- package/dist/parsers/lwc/js-visitor.js +354 -12
- package/dist/parsers/lwc/js-visitor.js.map +1 -1
- package/dist/parsers/lwc/omnidef.d.ts +10 -0
- package/dist/parsers/lwc/omnidef.d.ts.map +1 -0
- package/dist/parsers/lwc/omnidef.js +127 -0
- package/dist/parsers/lwc/omnidef.js.map +1 -0
- package/dist/parsers/lwc/xml-meta.d.ts.map +1 -1
- package/dist/parsers/lwc/xml-meta.js +16 -1
- package/dist/parsers/lwc/xml-meta.js.map +1 -1
- package/dist/parsers/object/formula-hop-resolver.d.ts +33 -0
- package/dist/parsers/object/formula-hop-resolver.d.ts.map +1 -0
- package/dist/parsers/object/formula-hop-resolver.js +60 -0
- package/dist/parsers/object/formula-hop-resolver.js.map +1 -0
- package/dist/parsers/object/formula-refs.d.ts +40 -0
- package/dist/parsers/object/formula-refs.d.ts.map +1 -0
- package/dist/parsers/object/formula-refs.js +129 -0
- package/dist/parsers/object/formula-refs.js.map +1 -0
- package/dist/parsers/object/object.d.ts +3 -0
- package/dist/parsers/object/object.d.ts.map +1 -1
- package/dist/parsers/object/object.js +54 -57
- package/dist/parsers/object/object.js.map +1 -1
- package/dist/parsers/omnistudio/data-transform.d.ts.map +1 -1
- package/dist/parsers/omnistudio/data-transform.js +40 -7
- package/dist/parsers/omnistudio/data-transform.js.map +1 -1
- package/dist/parsers/omnistudio/integration-procedure.d.ts.map +1 -1
- package/dist/parsers/omnistudio/integration-procedure.js +6 -6
- package/dist/parsers/omnistudio/integration-procedure.js.map +1 -1
- package/dist/parsers/omnistudio/overlap-detector.d.ts.map +1 -1
- package/dist/parsers/omnistudio/overlap-detector.js +29 -11
- package/dist/parsers/omnistudio/overlap-detector.js.map +1 -1
- package/dist/parsers/omnistudio/process.d.ts.map +1 -1
- package/dist/parsers/omnistudio/process.js +6 -6
- package/dist/parsers/omnistudio/process.js.map +1 -1
- package/dist/parsers/omnistudio/remote-refs.d.ts +11 -0
- package/dist/parsers/omnistudio/remote-refs.d.ts.map +1 -0
- package/dist/parsers/omnistudio/remote-refs.js +17 -0
- package/dist/parsers/omnistudio/remote-refs.js.map +1 -0
- package/dist/parsers/omnistudio/ui-card.d.ts.map +1 -1
- package/dist/parsers/omnistudio/ui-card.js +6 -6
- package/dist/parsers/omnistudio/ui-card.js.map +1 -1
- package/dist/parsers/resolver-prune.d.ts +14 -0
- package/dist/parsers/resolver-prune.d.ts.map +1 -0
- package/dist/parsers/resolver-prune.js +29 -0
- package/dist/parsers/resolver-prune.js.map +1 -0
- package/dist/parsers/rules/_engine.d.ts.map +1 -1
- package/dist/parsers/rules/_engine.js +4 -0
- package/dist/parsers/rules/_engine.js.map +1 -1
- package/dist/parsers/rules/_engine.ts +3 -0
- package/dist/parsers/rules/_loader.d.ts +8 -0
- package/dist/parsers/rules/_loader.d.ts.map +1 -1
- package/dist/parsers/rules/_loader.js +17 -0
- package/dist/parsers/rules/_loader.js.map +1 -1
- package/dist/parsers/rules/_loader.ts +19 -0
- package/dist/parsers/rules/_schema.d.ts +12 -12
- package/dist/parsers/rules/_selectors.d.ts +1 -0
- package/dist/parsers/rules/_selectors.d.ts.map +1 -1
- package/dist/parsers/rules/_selectors.js +6 -0
- package/dist/parsers/rules/_selectors.js.map +1 -1
- package/dist/parsers/rules/_selectors.ts +6 -0
- package/dist/parsers/rules/apex-component.yml +49 -4
- package/dist/parsers/rules/apex-page.yml +49 -4
- package/dist/parsers/rules/approval-process.yml +25 -5
- package/dist/parsers/rules/custom-metadata-type.yml +14 -7
- package/dist/parsers/rules/custom-setting.yml +24 -0
- package/dist/parsers/rules/custom-tab.yml +41 -0
- package/dist/parsers/rules/lightning-page.yml +4 -2
- package/dist/parsers/rules/workflow.yml +30 -10
- package/dist/parsers/vf/refs.d.ts +39 -0
- package/dist/parsers/vf/refs.d.ts.map +1 -0
- package/dist/parsers/vf/refs.js +152 -0
- package/dist/parsers/vf/refs.js.map +1 -0
- package/dist/parsers/vlocity/apex-resolver.d.ts +21 -0
- package/dist/parsers/vlocity/apex-resolver.d.ts.map +1 -0
- package/dist/parsers/vlocity/apex-resolver.js +115 -0
- package/dist/parsers/vlocity/apex-resolver.js.map +1 -0
- package/dist/parsers/vlocity/common.d.ts +72 -1
- package/dist/parsers/vlocity/common.d.ts.map +1 -1
- package/dist/parsers/vlocity/common.js +332 -2
- package/dist/parsers/vlocity/common.js.map +1 -1
- package/dist/parsers/vlocity/data-raptor.d.ts +9 -0
- package/dist/parsers/vlocity/data-raptor.d.ts.map +1 -1
- package/dist/parsers/vlocity/data-raptor.js +148 -17
- package/dist/parsers/vlocity/data-raptor.js.map +1 -1
- package/dist/parsers/vlocity/datapack-refs.d.ts +22 -0
- package/dist/parsers/vlocity/datapack-refs.d.ts.map +1 -0
- package/dist/parsers/vlocity/datapack-refs.js +126 -0
- package/dist/parsers/vlocity/datapack-refs.js.map +1 -0
- package/dist/parsers/vlocity/dr-relationship-resolver.d.ts +26 -0
- package/dist/parsers/vlocity/dr-relationship-resolver.d.ts.map +1 -0
- package/dist/parsers/vlocity/dr-relationship-resolver.js +137 -0
- package/dist/parsers/vlocity/dr-relationship-resolver.js.map +1 -0
- package/dist/parsers/vlocity/integration-procedure.d.ts.map +1 -1
- package/dist/parsers/vlocity/integration-procedure.js +15 -48
- package/dist/parsers/vlocity/integration-procedure.js.map +1 -1
- package/dist/parsers/vlocity/name-match-resolver.d.ts +21 -0
- package/dist/parsers/vlocity/name-match-resolver.d.ts.map +1 -0
- package/dist/parsers/vlocity/name-match-resolver.js +97 -0
- package/dist/parsers/vlocity/name-match-resolver.js.map +1 -0
- package/dist/parsers/vlocity/omni-script.d.ts.map +1 -1
- package/dist/parsers/vlocity/omni-script.js +18 -32
- package/dist/parsers/vlocity/omni-script.js.map +1 -1
- package/dist/parsers/vlocity/vlocity-card.d.ts.map +1 -1
- package/dist/parsers/vlocity/vlocity-card.js +30 -36
- package/dist/parsers/vlocity/vlocity-card.js.map +1 -1
- package/dist/render/mermaid/dependency-graph.d.ts.map +1 -1
- package/dist/render/mermaid/dependency-graph.js +13 -1
- package/dist/render/mermaid/dependency-graph.js.map +1 -1
- package/dist/render/mermaid/diff.d.ts.map +1 -1
- package/dist/render/mermaid/diff.js +4 -2
- package/dist/render/mermaid/diff.js.map +1 -1
- package/dist/render/mermaid/shared.d.ts +7 -0
- package/dist/render/mermaid/shared.d.ts.map +1 -1
- package/dist/render/mermaid/shared.js +15 -6
- package/dist/render/mermaid/shared.js.map +1 -1
- package/dist/render/sarif.d.ts.map +1 -1
- package/dist/render/sarif.js +1 -3
- package/dist/render/sarif.js.map +1 -1
- package/dist/storage/index.d.ts +3 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -2
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/interfaces.d.ts +212 -1
- package/dist/storage/interfaces.d.ts.map +1 -1
- package/dist/storage/sqlite/graph-store.d.ts +366 -3
- package/dist/storage/sqlite/graph-store.d.ts.map +1 -1
- package/dist/storage/sqlite/graph-store.js +1755 -68
- package/dist/storage/sqlite/graph-store.js.map +1 -1
- package/dist/storage/sqlite/migrations.d.ts +11 -0
- package/dist/storage/sqlite/migrations.d.ts.map +1 -1
- package/dist/storage/sqlite/migrations.js +245 -11
- package/dist/storage/sqlite/migrations.js.map +1 -1
- package/dist/storage/sqlite/rename-stability.d.ts +1 -1
- package/dist/storage/sqlite/rename-stability.d.ts.map +1 -1
- package/dist/storage/sqlite/rename-stability.js +2 -6
- package/dist/storage/sqlite/rename-stability.js.map +1 -1
- package/dist/storage/sqlite/snapshot-store.d.ts +79 -3
- package/dist/storage/sqlite/snapshot-store.d.ts.map +1 -1
- package/dist/storage/sqlite/snapshot-store.js +500 -100
- package/dist/storage/sqlite/snapshot-store.js.map +1 -1
- package/dist/storage/sqlite/snapshot-versions.d.ts +51 -0
- package/dist/storage/sqlite/snapshot-versions.d.ts.map +1 -0
- package/dist/storage/sqlite/snapshot-versions.js +209 -0
- package/dist/storage/sqlite/snapshot-versions.js.map +1 -0
- package/dist/storage/sqlite/vector-store.d.ts +12 -0
- package/dist/storage/sqlite/vector-store.d.ts.map +1 -1
- package/dist/storage/sqlite/vector-store.js +57 -14
- package/dist/storage/sqlite/vector-store.js.map +1 -1
- package/dist/util/process-owner.d.ts +35 -0
- package/dist/util/process-owner.d.ts.map +1 -0
- package/dist/util/process-owner.js +87 -0
- package/dist/util/process-owner.js.map +1 -0
- package/dist/util/worker-heap-cap.d.ts +10 -0
- package/dist/util/worker-heap-cap.d.ts.map +1 -0
- package/dist/util/worker-heap-cap.js +65 -0
- package/dist/util/worker-heap-cap.js.map +1 -0
- package/package.json +6 -7
- package/dist/analyze/__tests__/audit-graph.test.d.ts +0 -2
- package/dist/analyze/__tests__/audit-graph.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/audit-graph.test.js +0 -122
- package/dist/analyze/__tests__/audit-graph.test.js.map +0 -1
- package/dist/analyze/__tests__/cross-org-two-store.test.d.ts +0 -2
- package/dist/analyze/__tests__/cross-org-two-store.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/cross-org-two-store.test.js +0 -68
- package/dist/analyze/__tests__/cross-org-two-store.test.js.map +0 -1
- package/dist/analyze/__tests__/dead-code-confidence.test.d.ts +0 -2
- package/dist/analyze/__tests__/dead-code-confidence.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/dead-code-confidence.test.js +0 -66
- package/dist/analyze/__tests__/dead-code-confidence.test.js.map +0 -1
- package/dist/analyze/__tests__/deployment-manifest.test.d.ts +0 -2
- package/dist/analyze/__tests__/deployment-manifest.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/deployment-manifest.test.js +0 -66
- package/dist/analyze/__tests__/deployment-manifest.test.js.map +0 -1
- package/dist/analyze/__tests__/find-nodes.test.d.ts +0 -2
- package/dist/analyze/__tests__/find-nodes.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/find-nodes.test.js +0 -129
- package/dist/analyze/__tests__/find-nodes.test.js.map +0 -1
- package/dist/analyze/__tests__/findings.test.d.ts +0 -2
- package/dist/analyze/__tests__/findings.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/findings.test.js +0 -90
- package/dist/analyze/__tests__/findings.test.js.map +0 -1
- package/dist/analyze/__tests__/governor-risks-detection.test.d.ts +0 -2
- package/dist/analyze/__tests__/governor-risks-detection.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/governor-risks-detection.test.js +0 -70
- package/dist/analyze/__tests__/governor-risks-detection.test.js.map +0 -1
- package/dist/analyze/__tests__/populate.test.d.ts +0 -2
- package/dist/analyze/__tests__/populate.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/populate.test.js +0 -129
- package/dist/analyze/__tests__/populate.test.js.map +0 -1
- package/dist/analyze/__tests__/traversal-caps.test.d.ts +0 -2
- package/dist/analyze/__tests__/traversal-caps.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/traversal-caps.test.js +0 -129
- package/dist/analyze/__tests__/traversal-caps.test.js.map +0 -1
- package/dist/analyze/__tests__/wip-impact.test.d.ts +0 -2
- package/dist/analyze/__tests__/wip-impact.test.d.ts.map +0 -1
- package/dist/analyze/__tests__/wip-impact.test.js +0 -134
- package/dist/analyze/__tests__/wip-impact.test.js.map +0 -1
- package/dist/embedding/__tests__/embed.test.d.ts +0 -2
- package/dist/embedding/__tests__/embed.test.d.ts.map +0 -1
- package/dist/embedding/__tests__/embed.test.js +0 -72
- package/dist/embedding/__tests__/embed.test.js.map +0 -1
- package/dist/embedding/__tests__/queue.test.d.ts +0 -2
- package/dist/embedding/__tests__/queue.test.d.ts.map +0 -1
- package/dist/embedding/__tests__/queue.test.js +0 -64
- package/dist/embedding/__tests__/queue.test.js.map +0 -1
- package/dist/extractors/__tests__/network-egress.test.d.ts +0 -2
- package/dist/extractors/__tests__/network-egress.test.d.ts.map +0 -1
- package/dist/extractors/__tests__/network-egress.test.js +0 -32
- package/dist/extractors/__tests__/network-egress.test.js.map +0 -1
- package/dist/extractors/filesystem/__tests__/filesystem.test.d.ts +0 -2
- package/dist/extractors/filesystem/__tests__/filesystem.test.d.ts.map +0 -1
- package/dist/extractors/filesystem/__tests__/filesystem.test.js +0 -96
- package/dist/extractors/filesystem/__tests__/filesystem.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/_jsforce-mock.d.ts +0 -38
- package/dist/extractors/live-org/__tests__/_jsforce-mock.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/_jsforce-mock.js +0 -96
- package/dist/extractors/live-org/__tests__/_jsforce-mock.js.map +0 -1
- package/dist/extractors/live-org/__tests__/auth.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/auth.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/auth.test.js +0 -85
- package/dist/extractors/live-org/__tests__/auth.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/bulk-retrieve.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/bulk-retrieve.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/bulk-retrieve.test.js +0 -150
- package/dist/extractors/live-org/__tests__/bulk-retrieve.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/capabilities.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/capabilities.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/capabilities.test.js +0 -54
- package/dist/extractors/live-org/__tests__/capabilities.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/discovery.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/discovery.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/discovery.test.js +0 -55
- package/dist/extractors/live-org/__tests__/discovery.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/dispatch.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/dispatch.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/dispatch.test.js +0 -68
- package/dist/extractors/live-org/__tests__/dispatch.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/extractor-enrichment.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/extractor-enrichment.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/extractor-enrichment.test.js +0 -312
- package/dist/extractors/live-org/__tests__/extractor-enrichment.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/liveness.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/liveness.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/liveness.test.js +0 -148
- package/dist/extractors/live-org/__tests__/liveness.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.js +0 -174
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.js +0 -75
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.js +0 -135
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/pools.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/pools.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/pools.test.js +0 -75
- package/dist/extractors/live-org/__tests__/pools.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/rate-limit.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/rate-limit.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/rate-limit.test.js +0 -78
- package/dist/extractors/live-org/__tests__/rate-limit.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/read-only-proxy.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/read-only-proxy.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/read-only-proxy.test.js +0 -376
- package/dist/extractors/live-org/__tests__/read-only-proxy.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.js +0 -118
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/source-member.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/source-member.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/source-member.test.js +0 -84
- package/dist/extractors/live-org/__tests__/source-member.test.js.map +0 -1
- package/dist/extractors/live-org/__tests__/vlocity-runner.test.d.ts +0 -2
- package/dist/extractors/live-org/__tests__/vlocity-runner.test.d.ts.map +0 -1
- package/dist/extractors/live-org/__tests__/vlocity-runner.test.js +0 -115
- package/dist/extractors/live-org/__tests__/vlocity-runner.test.js.map +0 -1
- package/dist/ingest/__tests__/full-sync-deletion.test.d.ts +0 -2
- package/dist/ingest/__tests__/full-sync-deletion.test.d.ts.map +0 -1
- package/dist/ingest/__tests__/full-sync-deletion.test.js +0 -200
- package/dist/ingest/__tests__/full-sync-deletion.test.js.map +0 -1
- package/dist/ingest/__tests__/incremental-deletion.test.d.ts +0 -2
- package/dist/ingest/__tests__/incremental-deletion.test.d.ts.map +0 -1
- package/dist/ingest/__tests__/incremental-deletion.test.js +0 -92
- package/dist/ingest/__tests__/incremental-deletion.test.js.map +0 -1
- package/dist/ingest/__tests__/live-ingest.test.d.ts +0 -2
- package/dist/ingest/__tests__/live-ingest.test.d.ts.map +0 -1
- package/dist/ingest/__tests__/live-ingest.test.js +0 -155
- package/dist/ingest/__tests__/live-ingest.test.js.map +0 -1
- package/dist/ingest/__tests__/multi-org-orchestrator.test.d.ts +0 -2
- package/dist/ingest/__tests__/multi-org-orchestrator.test.d.ts.map +0 -1
- package/dist/ingest/__tests__/multi-org-orchestrator.test.js +0 -108
- package/dist/ingest/__tests__/multi-org-orchestrator.test.js.map +0 -1
- package/dist/ingest/__tests__/read-only-wrapping.test.d.ts +0 -2
- package/dist/ingest/__tests__/read-only-wrapping.test.d.ts.map +0 -1
- package/dist/ingest/__tests__/read-only-wrapping.test.js +0 -62
- package/dist/ingest/__tests__/read-only-wrapping.test.js.map +0 -1
- package/dist/parsers/__tests__/_harness.d.ts +0 -13
- package/dist/parsers/__tests__/_harness.d.ts.map +0 -1
- package/dist/parsers/__tests__/_harness.js +0 -84
- package/dist/parsers/__tests__/_harness.js.map +0 -1
- package/dist/parsers/__tests__/apex.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/apex.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/apex.golden.test.js +0 -28
- package/dist/parsers/__tests__/apex.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/cross-flavor.test.d.ts +0 -2
- package/dist/parsers/__tests__/cross-flavor.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/cross-flavor.test.js +0 -56
- package/dist/parsers/__tests__/cross-flavor.test.js.map +0 -1
- package/dist/parsers/__tests__/edge-provenance.test.d.ts +0 -2
- package/dist/parsers/__tests__/edge-provenance.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/edge-provenance.test.js +0 -44
- package/dist/parsers/__tests__/edge-provenance.test.js.map +0 -1
- package/dist/parsers/__tests__/flow.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/flow.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/flow.golden.test.js +0 -17
- package/dist/parsers/__tests__/flow.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/integration.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/integration.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/integration.golden.test.js +0 -31
- package/dist/parsers/__tests__/integration.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/long-tail.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/long-tail.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/long-tail.golden.test.js +0 -115
- package/dist/parsers/__tests__/long-tail.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/lwc-bindings.test.d.ts +0 -2
- package/dist/parsers/__tests__/lwc-bindings.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/lwc-bindings.test.js +0 -146
- package/dist/parsers/__tests__/lwc-bindings.test.js.map +0 -1
- package/dist/parsers/__tests__/lwc.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/lwc.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/lwc.golden.test.js +0 -16
- package/dist/parsers/__tests__/lwc.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/mcd-gap-fills.test.d.ts +0 -2
- package/dist/parsers/__tests__/mcd-gap-fills.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/mcd-gap-fills.test.js +0 -75
- package/dist/parsers/__tests__/mcd-gap-fills.test.js.map +0 -1
- package/dist/parsers/__tests__/object-inline-fields.test.d.ts +0 -2
- package/dist/parsers/__tests__/object-inline-fields.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/object-inline-fields.test.js +0 -115
- package/dist/parsers/__tests__/object-inline-fields.test.js.map +0 -1
- package/dist/parsers/__tests__/object.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/object.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/object.golden.test.js +0 -33
- package/dist/parsers/__tests__/object.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/omnistudio-overlap.test.d.ts +0 -2
- package/dist/parsers/__tests__/omnistudio-overlap.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/omnistudio-overlap.test.js +0 -163
- package/dist/parsers/__tests__/omnistudio-overlap.test.js.map +0 -1
- package/dist/parsers/__tests__/omnistudio.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/omnistudio.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/omnistudio.golden.test.js +0 -54
- package/dist/parsers/__tests__/omnistudio.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/reflection-walker.test.d.ts +0 -2
- package/dist/parsers/__tests__/reflection-walker.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/reflection-walker.test.js +0 -162
- package/dist/parsers/__tests__/reflection-walker.test.js.map +0 -1
- package/dist/parsers/__tests__/registry.test.d.ts +0 -2
- package/dist/parsers/__tests__/registry.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/registry.test.js +0 -23
- package/dist/parsers/__tests__/registry.test.js.map +0 -1
- package/dist/parsers/__tests__/security.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/security.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/security.golden.test.js +0 -31
- package/dist/parsers/__tests__/security.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/vlocity.golden.test.d.ts +0 -2
- package/dist/parsers/__tests__/vlocity.golden.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/vlocity.golden.test.js +0 -109
- package/dist/parsers/__tests__/vlocity.golden.test.js.map +0 -1
- package/dist/parsers/__tests__/worker-pool.test.d.ts +0 -2
- package/dist/parsers/__tests__/worker-pool.test.d.ts.map +0 -1
- package/dist/parsers/__tests__/worker-pool.test.js +0 -48
- package/dist/parsers/__tests__/worker-pool.test.js.map +0 -1
- package/dist/parsers/apex/__tests__/arity-resolver.test.d.ts +0 -2
- package/dist/parsers/apex/__tests__/arity-resolver.test.d.ts.map +0 -1
- package/dist/parsers/apex/__tests__/arity-resolver.test.js +0 -135
- package/dist/parsers/apex/__tests__/arity-resolver.test.js.map +0 -1
- package/dist/parsers/apex/__tests__/ast-extractor.test.d.ts +0 -2
- package/dist/parsers/apex/__tests__/ast-extractor.test.d.ts.map +0 -1
- package/dist/parsers/apex/__tests__/ast-extractor.test.js +0 -146
- package/dist/parsers/apex/__tests__/ast-extractor.test.js.map +0 -1
- package/dist/parsers/apex/__tests__/is-test-attribute.test.d.ts +0 -2
- package/dist/parsers/apex/__tests__/is-test-attribute.test.d.ts.map +0 -1
- package/dist/parsers/apex/__tests__/is-test-attribute.test.js +0 -54
- package/dist/parsers/apex/__tests__/is-test-attribute.test.js.map +0 -1
- package/dist/parsers/apex/__tests__/regex-arg-count.test.d.ts +0 -2
- package/dist/parsers/apex/__tests__/regex-arg-count.test.d.ts.map +0 -1
- package/dist/parsers/apex/__tests__/regex-arg-count.test.js +0 -82
- package/dist/parsers/apex/__tests__/regex-arg-count.test.js.map +0 -1
- package/dist/parsers/flow/__tests__/invocable-resolver.test.d.ts +0 -2
- package/dist/parsers/flow/__tests__/invocable-resolver.test.d.ts.map +0 -1
- package/dist/parsers/flow/__tests__/invocable-resolver.test.js +0 -91
- package/dist/parsers/flow/__tests__/invocable-resolver.test.js.map +0 -1
- package/dist/parsers/rules/__tests__/applies-to.test.d.ts +0 -2
- package/dist/parsers/rules/__tests__/applies-to.test.d.ts.map +0 -1
- package/dist/parsers/rules/__tests__/applies-to.test.js +0 -31
- package/dist/parsers/rules/__tests__/applies-to.test.js.map +0 -1
- package/dist/parsers/rules/__tests__/applies-to.test.ts +0 -40
- package/dist/parsers/rules/__tests__/engine.test.d.ts +0 -2
- package/dist/parsers/rules/__tests__/engine.test.d.ts.map +0 -1
- package/dist/parsers/rules/__tests__/engine.test.js +0 -127
- package/dist/parsers/rules/__tests__/engine.test.js.map +0 -1
- package/dist/parsers/rules/__tests__/engine.test.ts +0 -138
- package/dist/parsers/rules/__tests__/loader.test.d.ts +0 -2
- package/dist/parsers/rules/__tests__/loader.test.d.ts.map +0 -1
- package/dist/parsers/rules/__tests__/loader.test.js +0 -31
- package/dist/parsers/rules/__tests__/loader.test.js.map +0 -1
- package/dist/parsers/rules/__tests__/loader.test.ts +0 -37
- package/dist/parsers/rules/__tests__/schema.test.d.ts +0 -2
- package/dist/parsers/rules/__tests__/schema.test.d.ts.map +0 -1
- package/dist/parsers/rules/__tests__/schema.test.js +0 -33
- package/dist/parsers/rules/__tests__/schema.test.js.map +0 -1
- package/dist/parsers/rules/__tests__/schema.test.ts +0 -37
- package/dist/parsers/rules/__tests__/selectors.test.d.ts +0 -2
- package/dist/parsers/rules/__tests__/selectors.test.d.ts.map +0 -1
- package/dist/parsers/rules/__tests__/selectors.test.js +0 -51
- package/dist/parsers/rules/__tests__/selectors.test.js.map +0 -1
- package/dist/parsers/rules/__tests__/selectors.test.ts +0 -62
- package/dist/render/__tests__/sarif.test.d.ts +0 -2
- package/dist/render/__tests__/sarif.test.d.ts.map +0 -1
- package/dist/render/__tests__/sarif.test.js +0 -129
- package/dist/render/__tests__/sarif.test.js.map +0 -1
- package/dist/render/mermaid/__tests__/mermaid.test.d.ts +0 -2
- package/dist/render/mermaid/__tests__/mermaid.test.d.ts.map +0 -1
- package/dist/render/mermaid/__tests__/mermaid.test.js +0 -74
- package/dist/render/mermaid/__tests__/mermaid.test.js.map +0 -1
- package/dist/storage/__tests__/analysis-tables-migration.test.d.ts +0 -2
- package/dist/storage/__tests__/analysis-tables-migration.test.d.ts.map +0 -1
- package/dist/storage/__tests__/analysis-tables-migration.test.js +0 -44
- package/dist/storage/__tests__/analysis-tables-migration.test.js.map +0 -1
- package/dist/storage/__tests__/graph-store.test.d.ts +0 -2
- package/dist/storage/__tests__/graph-store.test.d.ts.map +0 -1
- package/dist/storage/__tests__/graph-store.test.js +0 -132
- package/dist/storage/__tests__/graph-store.test.js.map +0 -1
- package/dist/storage/__tests__/identifier.test.d.ts +0 -2
- package/dist/storage/__tests__/identifier.test.d.ts.map +0 -1
- package/dist/storage/__tests__/identifier.test.js +0 -35
- package/dist/storage/__tests__/identifier.test.js.map +0 -1
- package/dist/storage/__tests__/load-better-sqlite3.test.d.ts +0 -2
- package/dist/storage/__tests__/load-better-sqlite3.test.d.ts.map +0 -1
- package/dist/storage/__tests__/load-better-sqlite3.test.js +0 -65
- package/dist/storage/__tests__/load-better-sqlite3.test.js.map +0 -1
- package/dist/storage/__tests__/migrations.test.d.ts +0 -2
- package/dist/storage/__tests__/migrations.test.d.ts.map +0 -1
- package/dist/storage/__tests__/migrations.test.js +0 -93
- package/dist/storage/__tests__/migrations.test.js.map +0 -1
- package/dist/storage/__tests__/perf-50k.test.d.ts +0 -2
- package/dist/storage/__tests__/perf-50k.test.d.ts.map +0 -1
- package/dist/storage/__tests__/perf-50k.test.js +0 -67
- package/dist/storage/__tests__/perf-50k.test.js.map +0 -1
- package/dist/storage/__tests__/rename-stability.test.d.ts +0 -2
- package/dist/storage/__tests__/rename-stability.test.d.ts.map +0 -1
- package/dist/storage/__tests__/rename-stability.test.js +0 -135
- package/dist/storage/__tests__/rename-stability.test.js.map +0 -1
- package/dist/storage/__tests__/snapshot-store.test.d.ts +0 -2
- package/dist/storage/__tests__/snapshot-store.test.d.ts.map +0 -1
- package/dist/storage/__tests__/snapshot-store.test.js +0 -117
- package/dist/storage/__tests__/snapshot-store.test.js.map +0 -1
- package/dist/storage/__tests__/snippets.test.d.ts +0 -2
- package/dist/storage/__tests__/snippets.test.d.ts.map +0 -1
- package/dist/storage/__tests__/snippets.test.js +0 -88
- package/dist/storage/__tests__/snippets.test.js.map +0 -1
- package/dist/storage/__tests__/vector-store-load-failure.test.d.ts +0 -2
- package/dist/storage/__tests__/vector-store-load-failure.test.d.ts.map +0 -1
- package/dist/storage/__tests__/vector-store-load-failure.test.js +0 -42
- package/dist/storage/__tests__/vector-store-load-failure.test.js.map +0 -1
- package/dist/storage/__tests__/vector-store.test.d.ts +0 -2
- package/dist/storage/__tests__/vector-store.test.d.ts.map +0 -1
- package/dist/storage/__tests__/vector-store.test.js +0 -87
- package/dist/storage/__tests__/vector-store.test.js.map +0 -1
- package/dist/telemetry/__tests__/event-schema.test.d.ts +0 -2
- package/dist/telemetry/__tests__/event-schema.test.d.ts.map +0 -1
- package/dist/telemetry/__tests__/event-schema.test.js +0 -56
- package/dist/telemetry/__tests__/event-schema.test.js.map +0 -1
- package/dist/telemetry/__tests__/machine-id.test.d.ts +0 -2
- package/dist/telemetry/__tests__/machine-id.test.d.ts.map +0 -1
- package/dist/telemetry/__tests__/machine-id.test.js +0 -33
- package/dist/telemetry/__tests__/machine-id.test.js.map +0 -1
- package/dist/telemetry/__tests__/pipeline.test.d.ts +0 -2
- package/dist/telemetry/__tests__/pipeline.test.d.ts.map +0 -1
- package/dist/telemetry/__tests__/pipeline.test.js +0 -68
- package/dist/telemetry/__tests__/pipeline.test.js.map +0 -1
- package/dist/telemetry/__tests__/sanitizer.test.d.ts +0 -2
- package/dist/telemetry/__tests__/sanitizer.test.d.ts.map +0 -1
- package/dist/telemetry/__tests__/sanitizer.test.js +0 -143
- package/dist/telemetry/__tests__/sanitizer.test.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { discoverMetadataTypes } from "./discovery.js";
|
|
2
2
|
import { buildDispatchTable } from "./dispatch.js";
|
|
3
3
|
import { iterApex } from "./extractors/apex.js";
|
|
4
|
+
import { iterCustomSettings } from "./extractors/custom-settings.js";
|
|
4
5
|
import { iterFlow } from "./extractors/flow.js";
|
|
5
6
|
import { iterGenericMetadata } from "./extractors/generic-metadata.js";
|
|
6
7
|
import { iterIntegration } from "./extractors/integration.js";
|
|
@@ -9,6 +10,98 @@ import { iterObject } from "./extractors/object.js";
|
|
|
9
10
|
import { iterOmnistudio } from "./extractors/omnistudio.js";
|
|
10
11
|
import { iterSecurity } from "./extractors/security.js";
|
|
11
12
|
import { iterVlocity } from "./extractors/vlocity.js";
|
|
13
|
+
import { StopWaitingError, stopSignalContext } from "./rate-limit.js";
|
|
14
|
+
import { IncompleteSourceError, TypeUnreadableError, UNREADABLE_EARLY_STOP, isPlatformRefusal, withRetry, } from "./retry.js";
|
|
15
|
+
/** Report a parked wedge as a skip, at most once per entry. */
|
|
16
|
+
function reportWedgeSkip(entry, reason) {
|
|
17
|
+
if (entry.skipReported)
|
|
18
|
+
return;
|
|
19
|
+
entry.skipReported = true;
|
|
20
|
+
entry.onError?.(entry.label, new Error(reason));
|
|
21
|
+
console.log(`ingest: ${entry.label} ✗ skipped (${reason.slice(0, 80)})`);
|
|
22
|
+
}
|
|
23
|
+
function createWedgeCoordinator(warnings = [], overrides) {
|
|
24
|
+
const capEnv = Number.parseInt(process.env.SFGRAPH_MAX_BACKGROUND_WEDGES ?? "", 10);
|
|
25
|
+
// Default 32 (was 4): a full --rebuild on a large org wedges many slow/empty
|
|
26
|
+
// generic-metadata sources at the 90s first-yield watchdog AND the heavy Apex
|
|
27
|
+
// source; a cap of 4 evicted most of them (their data lost). The drain loop
|
|
28
|
+
// skips already-resolved entries cheaply, so a high cap costs little.
|
|
29
|
+
const cap = Number.isFinite(capEnv) && capEnv > 0 ? capEnv : 32;
|
|
30
|
+
const drainEnv = Number.parseInt(process.env.SFGRAPH_LATE_DRAIN_BUDGET_MS ?? "", 10);
|
|
31
|
+
// Default 300s (was 60s): the per-entry budget is TOTAL drain wall-clock.
|
|
32
|
+
// Apex needs ~75s to stream all classes once the Tooling pool frees up after
|
|
33
|
+
// the main loop; 60s clipped it mid-drain. Empty/fast entries still return
|
|
34
|
+
// `done` immediately and cost nothing, so the larger budget only helps the
|
|
35
|
+
// genuinely-heavy entries finish.
|
|
36
|
+
const drain = Number.isFinite(drainEnv) && drainEnv >= 0 ? drainEnv : 300_000;
|
|
37
|
+
return {
|
|
38
|
+
warnings,
|
|
39
|
+
backgroundWedges: [],
|
|
40
|
+
maxBackgroundWedges: overrides?.maxBackgroundWedges ?? cap,
|
|
41
|
+
lateDrainBudgetMs: overrides?.lateDrainBudgetMs ?? drain,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Turn a source failure into skip-report entries. An IncompleteSourceError
|
|
46
|
+
* is split: members the org refused deterministically become one
|
|
47
|
+
* `unreadable` entry, the rest one entry classified as before — so a source
|
|
48
|
+
* with both still gets re-run for the recoverable part, and an all-refused
|
|
49
|
+
* source is not re-run at all.
|
|
50
|
+
*/
|
|
51
|
+
export function skipEntriesFor(label, err) {
|
|
52
|
+
if (err instanceof IncompleteSourceError && err.failures.length > 0) {
|
|
53
|
+
const out = [];
|
|
54
|
+
const refused = err.failures.filter((f) => isPlatformRefusal(f.error));
|
|
55
|
+
if (refused.length > 0) {
|
|
56
|
+
out.push({ label, reason: describeUnreadable(err.source, refused), category: "unreadable" });
|
|
57
|
+
}
|
|
58
|
+
// Classify the recoverable rest per failure (review M5): the combined
|
|
59
|
+
// message holds member names and only the FIRST error, so one
|
|
60
|
+
// INSUFFICIENT_ACCESS member (or a name containing NOT_FOUND) mislabelled
|
|
61
|
+
// every other loss. One entry per category, each naming its members.
|
|
62
|
+
const byCategory = new Map();
|
|
63
|
+
for (const f of err.failures) {
|
|
64
|
+
if (isPlatformRefusal(f.error))
|
|
65
|
+
continue;
|
|
66
|
+
const msg = f.error instanceof Error ? f.error.message : String(f.error);
|
|
67
|
+
const cat = classifySkip(msg);
|
|
68
|
+
byCategory.set(cat, [...(byCategory.get(cat) ?? []), f]);
|
|
69
|
+
}
|
|
70
|
+
for (const [category, group] of byCategory) {
|
|
71
|
+
out.push({ label, reason: new IncompleteSourceError(err.source, group).message, category });
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
const reason = err?.message ?? String(err);
|
|
76
|
+
return [{ label, reason, category: classifySkip(reason) }];
|
|
77
|
+
}
|
|
78
|
+
/** Counts behind a source's unreadable failures: members refused, members
|
|
79
|
+
* never requested after an early stop, and whether the listing was refused. */
|
|
80
|
+
function unreadableCounts(refused) {
|
|
81
|
+
const members = refused.filter((f) => !(f.error instanceof TypeUnreadableError) && !f.name.startsWith("metadata.list "));
|
|
82
|
+
const unread = refused.reduce((n, f) => n + (f.error instanceof TypeUnreadableError ? f.error.unreadCount : 0), 0);
|
|
83
|
+
return { members, unread, listing: refused.some((f) => f.name.startsWith("metadata.list ")) };
|
|
84
|
+
}
|
|
85
|
+
function describeUnreadable(source, refused) {
|
|
86
|
+
const MAX_NAMES = 25;
|
|
87
|
+
const { members, unread, listing } = unreadableCounts(refused);
|
|
88
|
+
// The shared refusal of an early stop is its first member's (review N2);
|
|
89
|
+
// otherwise the first refusal recorded.
|
|
90
|
+
const stop = refused.find((f) => f.error instanceof TypeUnreadableError)?.error;
|
|
91
|
+
const first = stop?.cause ?? refused[0]?.error;
|
|
92
|
+
const firstMsg = first instanceof Error ? first.message : String(first ?? "");
|
|
93
|
+
if (listing && members.length === 0) {
|
|
94
|
+
// The type's listing itself was refused (e.g. ManagedTopic).
|
|
95
|
+
return `${source}: listing unreadable (org refused metadata.list); error: ${firstMsg}`;
|
|
96
|
+
}
|
|
97
|
+
const names = members.map((f) => f.name);
|
|
98
|
+
const shown = names.slice(0, MAX_NAMES).join(", ");
|
|
99
|
+
const more = names.length > MAX_NAMES ? ` (+${names.length - MAX_NAMES} more)` : "";
|
|
100
|
+
const stopped = unread > 0
|
|
101
|
+
? `; stopped reading the type after ${UNREADABLE_EARLY_STOP} identical refusals — ${unread} more member(s) not read`
|
|
102
|
+
: "";
|
|
103
|
+
return `${source}: ${members.length} member(s) unreadable (org refused): ${shown}${more}${stopped}; first error: ${firstMsg}`;
|
|
104
|
+
}
|
|
12
105
|
/** Best-effort classification so the end-of-run recommendation is targeted. */
|
|
13
106
|
function classifySkip(msg) {
|
|
14
107
|
const m = msg.toUpperCase();
|
|
@@ -34,27 +127,27 @@ export async function* mergeAsyncIterables(...iters) {
|
|
|
34
127
|
yield v;
|
|
35
128
|
}
|
|
36
129
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
130
|
+
export function mergeAsyncIterablesParallel(...args) {
|
|
131
|
+
// Disambiguate the two overloads. The 2-arg array+opts form is used by
|
|
132
|
+
// tests; the rest-args form is the production fan-out path.
|
|
133
|
+
let iters;
|
|
134
|
+
let opts;
|
|
135
|
+
if (args.length === 2 &&
|
|
136
|
+
Array.isArray(args[0]) &&
|
|
137
|
+
args[1] != null &&
|
|
138
|
+
typeof args[1] === "object" &&
|
|
139
|
+
!(args[1] instanceof Promise) &&
|
|
140
|
+
!(Symbol.asyncIterator in args[1])) {
|
|
141
|
+
iters = args[0];
|
|
142
|
+
opts = args[1];
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
iters = args;
|
|
146
|
+
opts = undefined;
|
|
147
|
+
}
|
|
148
|
+
return mergeAsyncIterablesParallelImpl(iters, opts);
|
|
149
|
+
}
|
|
150
|
+
async function* mergeAsyncIterablesParallelImpl(iters, opts) {
|
|
58
151
|
const envConcurrency = Number.parseInt(process.env.SFGRAPH_SOURCE_CONCURRENCY ?? "", 10);
|
|
59
152
|
// Raised 8 -> 12: a wider window lets Tooling-backed sources (apex, lwc)
|
|
60
153
|
// start immediately rather than wait behind the cohort of metadata-pool
|
|
@@ -62,22 +155,32 @@ export async function* mergeAsyncIterablesParallel(...iters) {
|
|
|
62
155
|
// which spend most of their time queued in Bottleneck. Per-pool concurrency
|
|
63
156
|
// still caps total HTTP fan-out, so this only opens up parallelism that
|
|
64
157
|
// was being throttled at the wrong layer.
|
|
65
|
-
const concurrency =
|
|
158
|
+
const concurrency = opts?.concurrency != null && opts.concurrency > 0
|
|
159
|
+
? opts.concurrency
|
|
160
|
+
: Number.isFinite(envConcurrency) && envConcurrency > 0
|
|
161
|
+
? envConcurrency
|
|
162
|
+
: 12;
|
|
66
163
|
const iterators = iters.map((it) => it[Symbol.asyncIterator]());
|
|
67
164
|
const pending = new Map();
|
|
68
165
|
let nextIterIdx = 0;
|
|
166
|
+
// Sub-stream failures, in the order they happened. A failed stream frees
|
|
167
|
+
// its slot like a finished one so its peers (and queued streams) still
|
|
168
|
+
// drain, but the failure is re-thrown once everything else is done — it is
|
|
169
|
+
// never mapped to a silent `done` (review M7; the swallowed-error shape
|
|
170
|
+
// behind the original ApexClass truncation). bulkRetrieve's sources are
|
|
171
|
+
// failSoft-wrapped and never reject, so this only affects direct callers.
|
|
172
|
+
const errors = [];
|
|
69
173
|
const advance = (idx) => {
|
|
70
174
|
const it = iterators[idx];
|
|
71
175
|
if (!it)
|
|
72
176
|
return;
|
|
73
|
-
pending.set(idx, it.next().then((result) => ({ idx, result }),
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
})));
|
|
177
|
+
pending.set(idx, it.next().then((result) => ({ idx, result }), (e) => {
|
|
178
|
+
errors.push(e);
|
|
179
|
+
return {
|
|
180
|
+
idx,
|
|
181
|
+
result: { value: undefined, done: true },
|
|
182
|
+
};
|
|
183
|
+
}));
|
|
81
184
|
};
|
|
82
185
|
// Prime the window with the first `concurrency` iterators.
|
|
83
186
|
while (pending.size < concurrency && nextIterIdx < iterators.length) {
|
|
@@ -96,61 +199,318 @@ export async function* mergeAsyncIterablesParallel(...iters) {
|
|
|
96
199
|
yield result.value;
|
|
97
200
|
advance(idx);
|
|
98
201
|
}
|
|
202
|
+
if (errors.length === 1)
|
|
203
|
+
throw errors[0];
|
|
204
|
+
if (errors.length > 1) {
|
|
205
|
+
throw new AggregateError(errors, `${errors.length} merged sources failed`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Per-source watchdog budgets. Centralized here so the failSoft wrapper and
|
|
210
|
+
* tests share the same constants.
|
|
211
|
+
*
|
|
212
|
+
* Phase 1.5 W1.5-01 contract: these are the budgets the watchdog uses, but
|
|
213
|
+
* the clock against which they measure starts at slot-acquisition time
|
|
214
|
+
* (i.e., on the FIRST `it.next()` call inside `failSoft`'s body), NOT at
|
|
215
|
+
* source registration. Queued-but-not-yet-executing sources accumulate
|
|
216
|
+
* ZERO clock time, so a wedge in one source can no longer cascade-kill
|
|
217
|
+
* its queued neighbors.
|
|
218
|
+
*
|
|
219
|
+
* Anti-feature reminder: do NOT raise these to "fix" a real wedge. The
|
|
220
|
+
* correct fix is per-source override (W1.5-future) or fixing the underlying
|
|
221
|
+
* pre-yield setup call. See `.planning/phase-1.5/PLAN.md` anti-features.
|
|
222
|
+
*/
|
|
223
|
+
const WATCHDOG_INACTIVITY_MS_DEFAULT = 5 * 60_000;
|
|
224
|
+
const WATCHDOG_FIRST_YIELD_MS_DEFAULT = 90_000;
|
|
225
|
+
/**
|
|
226
|
+
* Per-source watchdog overrides (the "per-source override" the anti-feature
|
|
227
|
+
* note above points to). Some sources legitimately need far longer than the
|
|
228
|
+
* 90s default to produce their FIRST record — most notably the Vlocity runner,
|
|
229
|
+
* which executes a long sequence of `vlocity_cmt` SObject queries and assembles
|
|
230
|
+
* DataPacks before yielding member #1, and can have multi-minute gaps between
|
|
231
|
+
* DataPack types once streaming. Raising the GLOBAL budget to accommodate it is
|
|
232
|
+
* wrong: it makes every other slow/empty source hold its merger slot 10x longer
|
|
233
|
+
* and starves the pool (observed: a 600s global first-yield stalled the whole
|
|
234
|
+
* fan-out behind a few empty generic sources). So scope the larger budget to
|
|
235
|
+
* the specific label only. Explicit env vars still win (debug/tests).
|
|
236
|
+
*/
|
|
237
|
+
const SOURCE_WATCHDOG_OVERRIDES = {
|
|
238
|
+
// Vlocity must stay INLINE: the post-merger background-drain cannot reliably
|
|
239
|
+
// recover it (it needs minutes to first-yield, longer than any sane drain
|
|
240
|
+
// budget, and competes for drain slots). Giving it a long inline budget lets
|
|
241
|
+
// it hold its DATA-pool slot and stream once the pool frees up. NB: do NOT
|
|
242
|
+
// do this for Tooling-pool sources like Apex — holding a scarce Tooling slot
|
|
243
|
+
// that long starves every other Tooling source and stalls the whole fan-out.
|
|
244
|
+
// Apex instead wedges fast (releasing its slot) and is recovered by the
|
|
245
|
+
// background-drain pass, which is sized generously in createWedgeCoordinator.
|
|
246
|
+
vlocity: { firstYieldMs: 20 * 60_000, inactivityMs: 10 * 60_000 },
|
|
247
|
+
};
|
|
248
|
+
/** Read watchdog budgets per-call so unit tests can override via env vars
|
|
249
|
+
* without restarting the process. Production env should leave these unset:
|
|
250
|
+
* ordinary sources get the documented 90s first-yield / 5min inactivity;
|
|
251
|
+
* a source in SOURCE_WATCHDOG_OVERRIDES gets its scoped budget instead. */
|
|
252
|
+
function readWatchdogBudgets(label) {
|
|
253
|
+
const fy = Number.parseInt(process.env.SFGRAPH_WATCHDOG_FIRST_YIELD_MS ?? "", 10);
|
|
254
|
+
const inact = Number.parseInt(process.env.SFGRAPH_WATCHDOG_INACTIVITY_MS ?? "", 10);
|
|
255
|
+
const override = label ? SOURCE_WATCHDOG_OVERRIDES[label] : undefined;
|
|
256
|
+
return {
|
|
257
|
+
firstYieldMs: Number.isFinite(fy) && fy > 0
|
|
258
|
+
? fy
|
|
259
|
+
: (override?.firstYieldMs ?? WATCHDOG_FIRST_YIELD_MS_DEFAULT),
|
|
260
|
+
inactivityMs: Number.isFinite(inact) && inact > 0
|
|
261
|
+
? inact
|
|
262
|
+
: (override?.inactivityMs ?? WATCHDOG_INACTIVITY_MS_DEFAULT),
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
/** Build the namespaced wedge warning string per the schema documented in
|
|
266
|
+
* PLAN.md (`wedge:<source>:<stage>:<detail>`). Centralized here so the
|
|
267
|
+
* format is stable across emit sites + grep-friendly. */
|
|
268
|
+
function fmtWedgeWarning(source, stage, detail) {
|
|
269
|
+
const parts = [`wedge:${source}:${stage}`];
|
|
270
|
+
for (const [k, v] of Object.entries(detail)) {
|
|
271
|
+
parts.push(`${k}=${v}`);
|
|
272
|
+
}
|
|
273
|
+
return parts.join(":");
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Enforce the background-wedge cap. When admitting a new entry would push
|
|
277
|
+
* the count above `maxBackgroundWedges`, mark the OLDEST entries' stop-
|
|
278
|
+
* waiting flags so their drain loops bail at the next iteration. Emits a
|
|
279
|
+
* `wedge:cap:backgroundWedgeAborted:...` warning per evicted entry. The
|
|
280
|
+
* iterator object itself is left in the set; the late-drain loop is what
|
|
281
|
+
* sees the flag and skips it. (We do NOT remove from `backgroundWedges`
|
|
282
|
+
* here so post-merger inspection still sees every wedge that ever fired
|
|
283
|
+
* during the run.)
|
|
284
|
+
*/
|
|
285
|
+
function enforceBackgroundWedgeCap(coordinator) {
|
|
286
|
+
const active = coordinator.backgroundWedges.filter((e) => !e.stopWaitingRef.value);
|
|
287
|
+
const overage = active.length - coordinator.maxBackgroundWedges;
|
|
288
|
+
if (overage <= 0)
|
|
289
|
+
return;
|
|
290
|
+
// Sort by registeredAt ascending; oldest first.
|
|
291
|
+
active.sort((a, b) => a.registeredAt - b.registeredAt);
|
|
292
|
+
for (let i = 0; i < overage; i += 1) {
|
|
293
|
+
const victim = active[i];
|
|
294
|
+
if (!victim)
|
|
295
|
+
continue;
|
|
296
|
+
victim.stopWaitingRef.value = true;
|
|
297
|
+
const ageMs = Date.now() - victim.registeredAt;
|
|
298
|
+
reportWedgeSkip(victim, `background wedge evicted (cap ${coordinator.maxBackgroundWedges}) after ${ageMs}ms — remaining rows not fetched`);
|
|
299
|
+
coordinator.warnings.push(fmtWedgeWarning("cap", "backgroundWedgeAborted", {
|
|
300
|
+
source: victim.label,
|
|
301
|
+
ageMs,
|
|
302
|
+
reason: "backgroundWedgeCapExceeded",
|
|
303
|
+
}));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Drain a single background-wedge iterator. Called once per wedged source,
|
|
308
|
+
* post-merger, with a wall-clock budget. Each iteration races the iterator's
|
|
309
|
+
* `it.next()` against the remaining budget. Records arriving inside the
|
|
310
|
+
* budget are yielded with `attributes.lateYield = true`. The pending HTTP
|
|
311
|
+
* request (if the wedge is on a network call) is NOT actively cancelled
|
|
312
|
+
* (W1.5-03's job); we just stop awaiting it.
|
|
313
|
+
*
|
|
314
|
+
* Bails immediately if `stopWaitingRef.value === true` (cap eviction).
|
|
315
|
+
*/
|
|
316
|
+
async function* drainBackgroundWedge(entry, budgetMs, warnings) {
|
|
317
|
+
const debug = process.env.SFGRAPH_DEBUG_INGEST === "1";
|
|
318
|
+
const startedAt = Date.now();
|
|
319
|
+
let lateCount = 0;
|
|
320
|
+
// Why the loop ended. Only "done" means the source finished; every other
|
|
321
|
+
// outcome loses rows and must become a skip (review I1).
|
|
322
|
+
let outcome = "evicted";
|
|
323
|
+
const BUDGET_SENTINEL = Symbol("late-drain budget");
|
|
324
|
+
while (!entry.stopWaitingRef.value) {
|
|
325
|
+
const remaining = startedAt + budgetMs - Date.now();
|
|
326
|
+
if (remaining <= 0) {
|
|
327
|
+
outcome = "budget";
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
// First iteration: consume the abandoned-but-still-pending `it.next()`
|
|
331
|
+
// promise from when the watchdog fired. Subsequent iterations call
|
|
332
|
+
// `iterator.next()` normally. Async-generator semantics queue
|
|
333
|
+
// concurrent `.next()` calls, so we MUST consume the pending one
|
|
334
|
+
// before issuing a new one — otherwise the late-yielded value goes
|
|
335
|
+
// to the abandoned promise and the drain sees the NEXT yield (or
|
|
336
|
+
// `done:true` if the generator is single-yield).
|
|
337
|
+
const nextPromise = entry.pendingFirstNext !== null
|
|
338
|
+
? entry.pendingFirstNext
|
|
339
|
+
: stopSignalContext.run(entry.stopWaitingRef, () => entry.iterator.next());
|
|
340
|
+
if (entry.pendingFirstNext !== null)
|
|
341
|
+
entry.pendingFirstNext = null;
|
|
342
|
+
let next;
|
|
343
|
+
let timer;
|
|
344
|
+
try {
|
|
345
|
+
next = await Promise.race([
|
|
346
|
+
nextPromise,
|
|
347
|
+
new Promise((resolve) => {
|
|
348
|
+
// A distinct sentinel (not a synthetic `done`) so budget exhaustion
|
|
349
|
+
// is never mistaken for the source finishing.
|
|
350
|
+
timer = setTimeout(() => resolve(BUDGET_SENTINEL), remaining);
|
|
351
|
+
}),
|
|
352
|
+
]);
|
|
353
|
+
}
|
|
354
|
+
catch (e) {
|
|
355
|
+
// Late-arriving error from the wedged iterator (e.g. an
|
|
356
|
+
// IncompleteSourceError after a truncated drain). Don't crash the
|
|
357
|
+
// drain; keep the warning AND record the skip.
|
|
358
|
+
const err = e;
|
|
359
|
+
const msg = err?.message ?? String(e);
|
|
360
|
+
warnings.push(fmtWedgeWarning(entry.label, "lateError", { error: msg.slice(0, 120) }));
|
|
361
|
+
outcome = "error";
|
|
362
|
+
if (!entry.skipReported) {
|
|
363
|
+
entry.skipReported = true;
|
|
364
|
+
entry.onError?.(entry.label, err instanceof Error ? err : new Error(msg));
|
|
365
|
+
console.log(`ingest: ${entry.label} ✗ skipped (${msg.slice(0, 80)})`);
|
|
366
|
+
}
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
if (timer)
|
|
371
|
+
clearTimeout(timer);
|
|
372
|
+
}
|
|
373
|
+
if (next === BUDGET_SENTINEL) {
|
|
374
|
+
outcome = "budget";
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
377
|
+
if (next.done) {
|
|
378
|
+
outcome = "done";
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
lateCount += 1;
|
|
382
|
+
const rec = next.value;
|
|
383
|
+
// Tag with lateYield so downstream consumers / tests can identify the
|
|
384
|
+
// record as having arrived after slot release.
|
|
385
|
+
const tagged = {
|
|
386
|
+
...rec,
|
|
387
|
+
attributes: { ...(rec.attributes ?? {}), lateYield: true },
|
|
388
|
+
};
|
|
389
|
+
yield tagged;
|
|
390
|
+
}
|
|
391
|
+
if (outcome === "budget") {
|
|
392
|
+
reportWedgeSkip(entry, `late-drain budget exhausted (${budgetMs}ms) after ${lateCount} late records — source did not finish`);
|
|
393
|
+
}
|
|
394
|
+
else if (outcome === "evicted") {
|
|
395
|
+
reportWedgeSkip(entry, "background wedge evicted before the late drain finished it");
|
|
396
|
+
}
|
|
397
|
+
if (lateCount > 0) {
|
|
398
|
+
const totalMs = Date.now() - entry.registeredAt;
|
|
399
|
+
warnings.push(fmtWedgeWarning(entry.label, "resolvedLate", {
|
|
400
|
+
totalMs,
|
|
401
|
+
records: lateCount,
|
|
402
|
+
}));
|
|
403
|
+
}
|
|
404
|
+
if (debug) {
|
|
405
|
+
console.log(`ingest: [debug] ${entry.label} background-wedge drain finished (${lateCount} late records, stopWaiting=${entry.stopWaitingRef.value})`);
|
|
406
|
+
}
|
|
99
407
|
}
|
|
100
|
-
/**
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
|
|
408
|
+
/**
|
|
409
|
+
* Wrap an iterable so a thrown error is captured + the stream ends cleanly
|
|
410
|
+
* instead of aborting the whole ingest. The error is recorded into a
|
|
411
|
+
* shared skip report (consumed at end-of-run) and a compact ✗ line is
|
|
412
|
+
* printed so the user sees something happened without the full error
|
|
413
|
+
* message scrolling past during the run.
|
|
414
|
+
*
|
|
415
|
+
* Phase 1.5 W1.5-01 + W1.5-02 contract:
|
|
416
|
+
*
|
|
417
|
+
* - The watchdog clock starts when this generator's BODY first executes
|
|
418
|
+
* (i.e., when the merger calls `.next()` on us for the first time —
|
|
419
|
+
* that's slot-acquisition time). Queued sources still inside
|
|
420
|
+
* `mergeAsyncIterablesParallel`'s waiting list accumulate ZERO clock
|
|
421
|
+
* time. Implemented via an internal `startedAtRef` that's written once
|
|
422
|
+
* on body entry; if the caller passes a `startedAtRef` we update it in
|
|
423
|
+
* place so the merger can observe the slot-acquisition moment.
|
|
424
|
+
*
|
|
425
|
+
* - On watchdog fire, we DO NOT throw (which would abort the merger's
|
|
426
|
+
* Promise.race for our slot AND lose the still-pending iterator).
|
|
427
|
+
* Instead we:
|
|
428
|
+
* 1. Emit a `wedge:<label>:firstYield:90s:...` (or `:inactivity:300s:`)
|
|
429
|
+
* warning into coordinator.warnings.
|
|
430
|
+
* 2. Register the still-pending iterator into coordinator.background
|
|
431
|
+
* Wedges with a stopWaitingRef. Enforce the cap (evict oldest).
|
|
432
|
+
* 3. RETURN from the generator. This cleanly releases the merger's
|
|
433
|
+
* slot — `pending.delete(idx)` runs in mergeAsyncIterablesParallel
|
|
434
|
+
* and the next queued source acquires the slot.
|
|
435
|
+
* Post-merger, the bulkRetrieve top-level fan-out drains the background
|
|
436
|
+
* wedge set; records arriving inside the late-drain budget are yielded
|
|
437
|
+
* with `attributes.lateYield = true`.
|
|
438
|
+
*/
|
|
439
|
+
async function* failSoft(label, factory, onError, coordinator,
|
|
440
|
+
/** Optional outer-visible clock cell. The merger does not currently read
|
|
441
|
+
* this, but the contract is "set by failSoft on body entry"; tests use
|
|
442
|
+
* it to assert slot-acquisition timing. */
|
|
443
|
+
startedAtRef) {
|
|
106
444
|
const debug = process.env.SFGRAPH_DEBUG_INGEST === "1";
|
|
445
|
+
// W1.5-01: the clock starts HERE — body-entry, which is slot-acquisition
|
|
446
|
+
// time. NOT at failSoft() invocation (that's source registration, which
|
|
447
|
+
// can be hundreds of seconds before the merger picks us out of the queue).
|
|
107
448
|
const startedAt = Date.now();
|
|
449
|
+
if (startedAtRef)
|
|
450
|
+
startedAtRef.value = startedAt;
|
|
108
451
|
let count = 0;
|
|
109
452
|
let started = false;
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
453
|
+
// Track last-yielded qualifiedName for diagnostic warnings — the smoking-
|
|
454
|
+
// gun field that names WHICH record was in flight when the wedge fired.
|
|
455
|
+
let lastYieldedQName = "<none>";
|
|
456
|
+
const { firstYieldMs, inactivityMs } = readWatchdogBudgets(label);
|
|
457
|
+
// W1.5-03: pre-allocate the per-source stop-signal at body entry and
|
|
458
|
+
// publish it into AsyncLocalStorage so any downstream rate-limit wrapper
|
|
459
|
+
// (`withTimeout`, `soqlWithTimeout`, `scheduleQuery`) inside the wedged
|
|
460
|
+
// iterator can observe `value = true` after cap-eviction flips it. Same
|
|
461
|
+
// ref is later attached to the BackgroundWedgeEntry so the keystone's
|
|
462
|
+
// `enforceBackgroundWedgeCap` flip propagates to in-flight calls without
|
|
463
|
+
// any per-extractor signature change. AsyncLocalStorage propagates across
|
|
464
|
+
// awaits within an async function started inside .run() — we factor the
|
|
465
|
+
// iterator into a helper started inside the .run() callback.
|
|
466
|
+
const stopWaitingRef = { value: false };
|
|
467
|
+
const it = stopSignalContext.run(stopWaitingRef, () => factory()[Symbol.asyncIterator]());
|
|
468
|
+
if (debug)
|
|
469
|
+
console.log(`ingest: [debug] ${label} ← invoked at ${startedAt}`);
|
|
126
470
|
try {
|
|
127
|
-
if (debug)
|
|
128
|
-
console.log(`ingest: [debug] ${label} ← invoked at ${startedAt}`);
|
|
129
|
-
const it = factory()[Symbol.asyncIterator]();
|
|
130
471
|
while (true) {
|
|
131
472
|
const remainingFirstYield = started
|
|
132
473
|
? Number.POSITIVE_INFINITY
|
|
133
474
|
: startedAt + firstYieldMs - Date.now();
|
|
134
475
|
const watchdogMs = Math.min(inactivityMs, remainingFirstYield);
|
|
135
|
-
|
|
136
|
-
|
|
476
|
+
const stage = started ? "inactivity" : "firstYield";
|
|
477
|
+
const stageDetail = started ? `${inactivityMs / 1000}s` : `${firstYieldMs / 1000}s`;
|
|
478
|
+
// Run each `.next()` synchronously inside the ALS context so awaits
|
|
479
|
+
// inside the underlying generator's body that call into rate-limit
|
|
480
|
+
// wrappers can resolve the stop-signal via `getStore()`.
|
|
481
|
+
const pending = stopSignalContext.run(stopWaitingRef, () => it.next());
|
|
482
|
+
let timer;
|
|
483
|
+
let wedged;
|
|
484
|
+
try {
|
|
485
|
+
wedged = await Promise.race([
|
|
486
|
+
pending.then((result) => ({ wedge: false, result })),
|
|
487
|
+
new Promise((resolve) => {
|
|
488
|
+
// watchdogMs may be <=0 if the budget is already burned (defensive
|
|
489
|
+
// — should be rare since the clock starts at body-entry). setTimeout
|
|
490
|
+
// with non-positive delay fires on the next event-loop tick, which
|
|
491
|
+
// is the correct wedge-immediately behavior.
|
|
492
|
+
timer = setTimeout(() => resolve({ wedge: true }), Math.max(0, watchdogMs));
|
|
493
|
+
}),
|
|
494
|
+
]);
|
|
137
495
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
496
|
+
finally {
|
|
497
|
+
// Clear on EVERY outcome. Clearing only when `pending` resolved left
|
|
498
|
+
// the ref'd timer (up to the 5 min inactivity budget) armed whenever
|
|
499
|
+
// the source threw, so a run whose last sources skipped held the
|
|
500
|
+
// process open after its final line (exit hang, 2026-10-09).
|
|
501
|
+
if (timer)
|
|
502
|
+
clearTimeout(timer);
|
|
503
|
+
}
|
|
504
|
+
if (wedged.wedge) {
|
|
505
|
+
// Hand off the still-pending it.next() so the drain can consume
|
|
506
|
+
// it directly — see BackgroundWedgeEntry.pendingFirstNext.
|
|
507
|
+
emitWedge(stage, stageDetail, pending);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
const next = wedged.result;
|
|
147
511
|
if (next.done)
|
|
148
512
|
break;
|
|
149
|
-
|
|
150
|
-
started = true;
|
|
151
|
-
console.log(`ingest: ${label} → starting…`);
|
|
152
|
-
}
|
|
153
|
-
count += 1;
|
|
513
|
+
recordYield(next.value);
|
|
154
514
|
yield next.value;
|
|
155
515
|
}
|
|
156
516
|
if (started) {
|
|
@@ -163,7 +523,30 @@ async function* failSoft(label, factory, onError) {
|
|
|
163
523
|
catch (e) {
|
|
164
524
|
const err = e;
|
|
165
525
|
onError?.(label, err);
|
|
166
|
-
|
|
526
|
+
// Print the unreadable and recoverable counts separately (review M6):
|
|
527
|
+
// the combined message counts both as "not fetched after retries".
|
|
528
|
+
let detail = err?.message?.slice(0, 80) ?? "unknown";
|
|
529
|
+
let verdict = "skipped";
|
|
530
|
+
if (err instanceof IncompleteSourceError && err.failures.length > 0) {
|
|
531
|
+
const refused = err.failures.filter((f) => isPlatformRefusal(f.error));
|
|
532
|
+
const lost = err.failures.length - refused.length;
|
|
533
|
+
if (refused.length > 0) {
|
|
534
|
+
const { members, unread, listing } = unreadableCounts(refused);
|
|
535
|
+
const parts = [];
|
|
536
|
+
if (lost > 0)
|
|
537
|
+
parts.push(`${lost} member(s) not fetched`);
|
|
538
|
+
if (listing)
|
|
539
|
+
parts.push("listing refused");
|
|
540
|
+
if (members.length > 0)
|
|
541
|
+
parts.push(`${members.length} member(s) unreadable`);
|
|
542
|
+
if (unread > 0)
|
|
543
|
+
parts.push(`${unread} not read after early stop`);
|
|
544
|
+
detail = parts.join(", ");
|
|
545
|
+
if (lost === 0)
|
|
546
|
+
verdict = "unreadable";
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
console.log(`ingest: ${label} ✗ ${verdict} (${detail})`);
|
|
167
550
|
if (debug) {
|
|
168
551
|
console.error(`ingest: [debug] ${label} failure detail: ${err?.message ?? String(err)}`);
|
|
169
552
|
if (err?.stack)
|
|
@@ -175,6 +558,65 @@ async function* failSoft(label, factory, onError) {
|
|
|
175
558
|
console.log(`ingest: [debug] ${label} → finalised (${count} records, ${Date.now() - startedAt}ms)`);
|
|
176
559
|
}
|
|
177
560
|
}
|
|
561
|
+
/** Inline helper: extracts qualifiedName-ish text from a RawMember for the
|
|
562
|
+
* `lastYielded=...` diagnostic field. Safe against undefined. */
|
|
563
|
+
function recordYield(v) {
|
|
564
|
+
if (!started) {
|
|
565
|
+
started = true;
|
|
566
|
+
console.log(`ingest: ${label} → starting…`);
|
|
567
|
+
}
|
|
568
|
+
count += 1;
|
|
569
|
+
const ref = v.ref;
|
|
570
|
+
if (ref) {
|
|
571
|
+
lastYieldedQName = `${ref.memberType}/${ref.memberName}`;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Slot-release + soft-isolate on watchdog fire. Two side effects:
|
|
576
|
+
* 1. Push a `wedge:<label>:<stage>:<detail>` warning into the shared sink.
|
|
577
|
+
* 2. Park the still-pending iterator into the background-wedge set so
|
|
578
|
+
* the post-merger late-drain pass can capture any records that
|
|
579
|
+
* eventually arrive. Enforce the cap (oldest evicted with a
|
|
580
|
+
* `backgroundWedgeAborted` warning).
|
|
581
|
+
* The generator then RETURNS (caller is `for await` of the merger; the
|
|
582
|
+
* merger sees `done:true` and releases the slot).
|
|
583
|
+
*/
|
|
584
|
+
function emitWedge(stage, stageDetail, pendingFirstNext) {
|
|
585
|
+
const wedgedFor = Date.now() - startedAt;
|
|
586
|
+
if (coordinator) {
|
|
587
|
+
// Schema (PLAN.md): `wedge:<label>:<stage>:<stageDetail>:<k=v>:<k=v>`.
|
|
588
|
+
// <stageDetail> is a positional value (e.g. "90s"), not a key=value.
|
|
589
|
+
const w = `wedge:${label}:${stage}:${stageDetail}` +
|
|
590
|
+
`:lastYielded=${lastYieldedQName}` +
|
|
591
|
+
`:wedgedForMs=${wedgedFor}`;
|
|
592
|
+
coordinator.warnings.push(w);
|
|
593
|
+
console.log(`ingest: ${label} ⚠ wedged (${stage} ${stageDetail}); slot released, draining in background`);
|
|
594
|
+
// W1.5-03: reuse the SAME stopWaitingRef that was published into ALS
|
|
595
|
+
// at body entry. When enforceBackgroundWedgeCap later flips this ref's
|
|
596
|
+
// `.value = true` on cap eviction, any in-flight rate-limit wrapper
|
|
597
|
+
// inside the wedged iterator's continuing background pumps will see
|
|
598
|
+
// the flag through `stopSignalContext.getStore()` and reject with
|
|
599
|
+
// `StopWaitingError` quickly. The underlying jsforce HTTP call still
|
|
600
|
+
// leaks until socket idle timeout — documented in rate-limit.ts.
|
|
601
|
+
coordinator.backgroundWedges.push({
|
|
602
|
+
label,
|
|
603
|
+
iterator: it,
|
|
604
|
+
pendingFirstNext,
|
|
605
|
+
registeredAt: Date.now(),
|
|
606
|
+
stopWaitingRef,
|
|
607
|
+
...(onError ? { onError } : {}),
|
|
608
|
+
});
|
|
609
|
+
enforceBackgroundWedgeCap(coordinator);
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
// No coordinator (e.g. unit-test path that didn't wire one up, or
|
|
613
|
+
// back-compat caller): fall back to the old "log+skip" behavior so
|
|
614
|
+
// the caller still gets observable feedback.
|
|
615
|
+
const msg = `source watchdog (${stage} ${stageDetail}): no record yielded — pool jammed or call wedged`;
|
|
616
|
+
onError?.(label, new Error(msg));
|
|
617
|
+
console.log(`ingest: ${label} ✗ skipped (${msg.slice(0, 80)})`);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
178
620
|
}
|
|
179
621
|
/** Typed-extractor ownership map: which XML type names a dedicated extractor covers. */
|
|
180
622
|
const APEX_TYPES = new Set(["ApexClass", "ApexTrigger"]);
|
|
@@ -291,10 +733,29 @@ const GENERIC_TYPE_WHITELIST = new Set([
|
|
|
291
733
|
"OmniUiCard",
|
|
292
734
|
"OmniProcess",
|
|
293
735
|
]);
|
|
736
|
+
/**
|
|
737
|
+
* Types whose data is fully captured by a CONTAINER type, so routing them
|
|
738
|
+
* individually only produces value-less opaque duplicates that clobber the
|
|
739
|
+
* container's richer nodes. `CustomLabel` (singular) is covered by the
|
|
740
|
+
* `CustomLabels` container — whose rule extracts each label's value/language;
|
|
741
|
+
* the singular path would emit `CustomLabel:Name` nodes with no value and,
|
|
742
|
+
* depending on merge order, overwrite the real ones. Skip them.
|
|
743
|
+
*/
|
|
744
|
+
const CONTAINER_COVERED_TYPES = new Set(["CustomLabel"]);
|
|
294
745
|
function shouldRouteGeneric(type) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
746
|
+
// Never route a type a container already covers with richer data.
|
|
747
|
+
if (CONTAINER_COVERED_TYPES.has(type))
|
|
748
|
+
return false;
|
|
749
|
+
// Default: route EVERY long-tail metadata type through the generic
|
|
750
|
+
// extractor so the graph — and therefore semantic search — covers the org
|
|
751
|
+
// completely. Anything without a dedicated extractor still becomes a typed
|
|
752
|
+
// node (the rule parsers key off the type name) or an opaque node, which is
|
|
753
|
+
// what search needs. The old curated whitelist silently dropped ~250
|
|
754
|
+
// discovered types (search returned nothing for them). Set
|
|
755
|
+
// SFGRAPH_GENERIC_WHITELIST_ONLY=1 to restore the restricted subset.
|
|
756
|
+
if (process.env.SFGRAPH_GENERIC_WHITELIST_ONLY === "1")
|
|
757
|
+
return GENERIC_TYPE_WHITELIST.has(type);
|
|
758
|
+
return true;
|
|
298
759
|
}
|
|
299
760
|
export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
300
761
|
// Back-compat: callers used to pass IngestSkipReport directly as the 4th arg.
|
|
@@ -304,24 +765,58 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
304
765
|
: opts;
|
|
305
766
|
const skipReport = normalized.skipReport;
|
|
306
767
|
const onlyLabels = normalized.onlyLabels;
|
|
307
|
-
//
|
|
308
|
-
//
|
|
309
|
-
//
|
|
768
|
+
// An explicit re-run (--retry-skipped / --only) reads every member of the
|
|
769
|
+
// generic types it names: no early stop (review N1c). Every generic source
|
|
770
|
+
// such a run launches was named, directly or via `discovery`.
|
|
771
|
+
const genericOpts = { earlyStop: !(onlyLabels && normalized.explicitOnlyLabels) };
|
|
772
|
+
// Phase 1.5 W1.5-02 coordinator. Built only when a warnings sink was
|
|
773
|
+
// supplied — without one, no place to push wedge strings, so the legacy
|
|
774
|
+
// "watchdog fires → skip entry" behavior is preserved. The coordinator
|
|
775
|
+
// owns the background-wedge cap + late-drain budget.
|
|
776
|
+
const coordinator = normalized.warnings
|
|
777
|
+
? createWedgeCoordinator(normalized.warnings)
|
|
778
|
+
: undefined;
|
|
779
|
+
const onSkip = skipReport
|
|
780
|
+
? (label, err) => {
|
|
781
|
+
skipReport.skips.push(...skipEntriesFor(label, err));
|
|
782
|
+
}
|
|
783
|
+
: undefined;
|
|
784
|
+
/** Record a skip for a label the --only filter selects (a pre-fan-out
|
|
785
|
+
* failure under an unrelated `--only` is not this run's loss). */
|
|
786
|
+
const skipIfSelected = (label, err, selected) => {
|
|
787
|
+
if (onlyLabels && !selected)
|
|
788
|
+
return;
|
|
789
|
+
onSkip?.(label, err);
|
|
790
|
+
console.log(`ingest: ${label} ✗ skipped (${err.message.slice(0, 80)})`);
|
|
791
|
+
};
|
|
792
|
+
// Discover the type list this org actually supports. Retried like every
|
|
793
|
+
// other fetch. If it still fails, fall back to invoking every dedicated
|
|
794
|
+
// extractor AND record a `discovery` skip: without the type list every
|
|
795
|
+
// generic:<Type> source (and every child type) is never invoked, which
|
|
796
|
+
// used to be silent (review I2). `--retry-skipped` feeds `discovery` back
|
|
797
|
+
// as an only-label, which selects every generic source below.
|
|
310
798
|
let types = [];
|
|
311
799
|
try {
|
|
312
|
-
types = await discoverMetadataTypes(conn);
|
|
800
|
+
types = await withRetry(() => discoverMetadataTypes(conn));
|
|
313
801
|
}
|
|
314
|
-
catch {
|
|
802
|
+
catch (e) {
|
|
315
803
|
types = [];
|
|
804
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
805
|
+
skipIfSelected("discovery", new Error(`metadata discovery failed — generic metadata types not fetched: ${err.message}`, {
|
|
806
|
+
cause: err,
|
|
807
|
+
}), !onlyLabels ||
|
|
808
|
+
onlyLabels.has("discovery") ||
|
|
809
|
+
[...onlyLabels].some((l) => l.startsWith("generic:")));
|
|
810
|
+
}
|
|
811
|
+
// Capability probes that failed transiently (not "absent"): the gated
|
|
812
|
+
// source was not invoked, so it is a skip under that source's label.
|
|
813
|
+
for (const pe of caps.probeErrors ?? []) {
|
|
814
|
+
if (!pe.source)
|
|
815
|
+
continue;
|
|
816
|
+
skipIfSelected(pe.source, new Error(`capability probe ${pe.probe} failed — source not run: ${pe.error}`), onlyLabels?.has(pe.source) ?? true);
|
|
316
817
|
}
|
|
317
818
|
const sources = [];
|
|
318
819
|
const invoked = new Set(); // source-key dedup
|
|
319
|
-
const onSkip = skipReport
|
|
320
|
-
? (label, err) => {
|
|
321
|
-
const reason = err?.message ?? String(err);
|
|
322
|
-
skipReport.skips.push({ label, reason, category: classifySkip(reason) });
|
|
323
|
-
}
|
|
324
|
-
: undefined;
|
|
325
820
|
const invoke = (key, factory) => {
|
|
326
821
|
if (invoked.has(key))
|
|
327
822
|
return;
|
|
@@ -329,14 +824,19 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
329
824
|
// --only filter: when onlyLabels is set, skip any source not in the set.
|
|
330
825
|
// Filter applies to the exact source key ('apex', 'generic:Profile', etc.)
|
|
331
826
|
// for precise targeting of retry/partial-refresh flows.
|
|
332
|
-
|
|
827
|
+
// A `discovery` only-label (from a skipped discovery) selects every
|
|
828
|
+
// generic source — those are what a failed discovery lost.
|
|
829
|
+
if (onlyLabels &&
|
|
830
|
+
!onlyLabels.has(key) &&
|
|
831
|
+
!(onlyLabels.has("discovery") && key.startsWith("generic:"))) {
|
|
333
832
|
return;
|
|
833
|
+
}
|
|
334
834
|
// Each source is wrapped fail-soft so one failing type (e.g. a metadata
|
|
335
835
|
// category the user's profile lacks access to) doesn't abort the whole
|
|
336
836
|
// ingest. The wrapper records the source label + error into skipReport
|
|
337
837
|
// (consumed at end of run for a consolidated summary) and ends the
|
|
338
838
|
// stream cleanly.
|
|
339
|
-
sources.push(failSoft(key, factory, onSkip));
|
|
839
|
+
sources.push(failSoft(key, factory, onSkip, coordinator));
|
|
340
840
|
};
|
|
341
841
|
if (types.length === 0) {
|
|
342
842
|
// Discovery unavailable: invoke every dedicated extractor once.
|
|
@@ -360,7 +860,7 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
360
860
|
invoke("lwc", () => iterLwc(conn));
|
|
361
861
|
else if (shouldRouteGeneric(type)) {
|
|
362
862
|
routedGeneric += 1;
|
|
363
|
-
invoke(`generic:${type}`, () => iterGenericMetadata(conn, String(orgId), type));
|
|
863
|
+
invoke(`generic:${type}`, () => iterGenericMetadata(conn, String(orgId), type, {}, genericOpts));
|
|
364
864
|
}
|
|
365
865
|
else {
|
|
366
866
|
skippedGeneric += 1;
|
|
@@ -377,7 +877,7 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
377
877
|
invoke("integration", () => iterIntegration(conn));
|
|
378
878
|
else if (shouldRouteGeneric(type)) {
|
|
379
879
|
routedGeneric += 1;
|
|
380
|
-
invoke(`generic:${type}`, () => iterGenericMetadata(conn, String(orgId), type));
|
|
880
|
+
invoke(`generic:${type}`, () => iterGenericMetadata(conn, String(orgId), type, {}, genericOpts));
|
|
381
881
|
}
|
|
382
882
|
else {
|
|
383
883
|
skippedGeneric += 1;
|
|
@@ -394,12 +894,54 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
394
894
|
break;
|
|
395
895
|
}
|
|
396
896
|
}
|
|
897
|
+
// Child metadata types (ValidationRule, ListView, CompactLayout, FieldSet,
|
|
898
|
+
// WebLink, BusinessProcess, ...) are returned by describe() only as
|
|
899
|
+
// `childXmlNames` of a parent (mostly CustomObject), never as top-level
|
|
900
|
+
// types — so the dispatch loop above never fetches them. Most ARE
|
|
901
|
+
// independently listable via metadata.list, so route each through the
|
|
902
|
+
// generic extractor. This is how validation rules / list views on STANDARD
|
|
903
|
+
// objects get captured — iterObject only sees children embedded in the
|
|
904
|
+
// custom objects it reads, missing the bulk that live on Account/Case/etc.
|
|
905
|
+
// Children that aren't independently listable fail-soft to nothing. Skip
|
|
906
|
+
// children already owned by a dedicated extractor or dispatched above.
|
|
907
|
+
if (process.env.SFGRAPH_GENERIC_WHITELIST_ONLY !== "1") {
|
|
908
|
+
const typedOwned = new Set([
|
|
909
|
+
...APEX_TYPES,
|
|
910
|
+
...LWC_TYPES,
|
|
911
|
+
...FLOW_TYPES,
|
|
912
|
+
...OBJECT_TYPES,
|
|
913
|
+
...SECURITY_TYPES,
|
|
914
|
+
...INTEGRATION_TYPES,
|
|
915
|
+
"CustomField", // fetched in bulk by iterObject; re-listing is wasteful
|
|
916
|
+
]);
|
|
917
|
+
const childTypes = new Set();
|
|
918
|
+
for (const t of types)
|
|
919
|
+
for (const c of t.childXmlNames)
|
|
920
|
+
childTypes.add(c);
|
|
921
|
+
for (const child of childTypes) {
|
|
922
|
+
if (dispatch.has(child) || typedOwned.has(child))
|
|
923
|
+
continue;
|
|
924
|
+
if (CONTAINER_COVERED_TYPES.has(child))
|
|
925
|
+
continue; // CustomLabel ⊂ CustomLabels
|
|
926
|
+
invoke(`generic:${child}`, () => iterGenericMetadata(conn, String(orgId), child, {}, genericOpts));
|
|
927
|
+
}
|
|
928
|
+
}
|
|
397
929
|
}
|
|
398
930
|
if (caps.vlocityLegacy) {
|
|
399
931
|
invoke("vlocity", () => iterVlocity(conn, caps, String(orgId), onSkip));
|
|
400
932
|
}
|
|
933
|
+
// Custom Setting ROW capture — self-guards (yields nothing if the org has no
|
|
934
|
+
// custom settings or EntityDefinition is unavailable), so invoke always.
|
|
935
|
+
invoke("custom-settings", () => iterCustomSettings(conn, String(orgId)));
|
|
401
936
|
if (caps.omnistudioOncore) {
|
|
402
|
-
|
|
937
|
+
// When the Metadata-API retrieve path is enabled it covers
|
|
938
|
+
// OmniDataTransform and OmniUiCard with higher fidelity — skip them on
|
|
939
|
+
// the SOQL path so the same component is not ingested twice (the
|
|
940
|
+
// retrieve XML would otherwise clobber the SOQL-enriched node, and
|
|
941
|
+
// vice versa, nondeterministically by merge order).
|
|
942
|
+
invoke("omnistudio", () => iterOmnistudio(conn, normalized.enableOmnistudioRetrieve
|
|
943
|
+
? { skipTypes: new Set(["OmniDataTransform", "OmniUiCard"]) }
|
|
944
|
+
: {}));
|
|
403
945
|
if (normalized.enableOmnistudioRetrieve) {
|
|
404
946
|
invoke("omnistudio-retrieve", async function* () {
|
|
405
947
|
const { iterOmnistudioRetrieve } = await import("./extractors/omnistudio-retrieve.js");
|
|
@@ -410,10 +952,16 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
410
952
|
});
|
|
411
953
|
}
|
|
412
954
|
}
|
|
413
|
-
// Log the generic-type
|
|
414
|
-
// skip-vs-route decision visible without --debug.
|
|
955
|
+
// Log the generic-type routing summary once at fan-out start — makes the
|
|
956
|
+
// skip-vs-route decision visible without --debug. The default is FULL
|
|
957
|
+
// coverage (every discovered type routed); the opt-out is
|
|
958
|
+
// SFGRAPH_GENERIC_WHITELIST_ONLY=1 (restricts to the curated subset).
|
|
415
959
|
if (types.length > 0) {
|
|
416
|
-
|
|
960
|
+
const whitelistOnly = process.env.SFGRAPH_GENERIC_WHITELIST_ONLY === "1";
|
|
961
|
+
const mode = whitelistOnly
|
|
962
|
+
? "curated whitelist only (SFGRAPH_GENERIC_WHITELIST_ONLY=1) — unset to route all"
|
|
963
|
+
: "full coverage (all discovered types) — set SFGRAPH_GENERIC_WHITELIST_ONLY=1 to restrict";
|
|
964
|
+
console.log(`ingest: dispatch routed=${sources.length} sources (${types.length} discovered metadata types; ${mode})`);
|
|
417
965
|
}
|
|
418
966
|
// Parallel by default: fan out across all source iterators so different
|
|
419
967
|
// pools (Tooling/Metadata/Data) saturate simultaneously. Escape hatch:
|
|
@@ -421,5 +969,69 @@ export async function* bulkRetrieve(conn, caps, orgId, opts = {}) {
|
|
|
421
969
|
// anyone who hits an ordering bug or wants the old log layout.
|
|
422
970
|
const sequential = process.env.SFGRAPH_SEQUENTIAL_SOURCES === "1";
|
|
423
971
|
yield* sequential ? mergeAsyncIterables(...sources) : mergeAsyncIterablesParallel(...sources);
|
|
972
|
+
// Phase 1.5 W1.5-02 late-yield drain. When the merger has finished its
|
|
973
|
+
// main loop (all live slots cleared), drain any background-wedge iterators
|
|
974
|
+
// for the configured budget. Records arriving inside the budget are
|
|
975
|
+
// yielded with `attributes.lateYield = true`. Iterators whose stopWaiting
|
|
976
|
+
// flag was set by the cap-eviction path skip immediately. Anything still
|
|
977
|
+
// unresolved after the budget is dropped on the floor — its underlying
|
|
978
|
+
// jsforce HTTP request continues running until libuv tears it down at
|
|
979
|
+
// process exit (W1.5-03 will surface a "stop-waiting" semantic for this).
|
|
980
|
+
if (coordinator &&
|
|
981
|
+
coordinator.backgroundWedges.length > 0 &&
|
|
982
|
+
coordinator.lateDrainBudgetMs <= 0) {
|
|
983
|
+
// Late drain disabled (SFGRAPH_LATE_DRAIN_BUDGET_MS=0): every parked
|
|
984
|
+
// wedge is abandoned, so each one is a skip, not a silent loss.
|
|
985
|
+
for (const entry of coordinator.backgroundWedges) {
|
|
986
|
+
reportWedgeSkip(entry, "wedged and late drain disabled — source did not finish");
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
else if (coordinator && coordinator.backgroundWedges.length > 0) {
|
|
990
|
+
if (process.env.SFGRAPH_DEBUG_INGEST === "1") {
|
|
991
|
+
console.log(`ingest: [debug] late-drain pass: ${coordinator.backgroundWedges.length} background wedge(s), budget=${coordinator.lateDrainBudgetMs}ms`);
|
|
992
|
+
}
|
|
993
|
+
for (const entry of coordinator.backgroundWedges) {
|
|
994
|
+
yield* drainBackgroundWedge(entry, coordinator.lateDrainBudgetMs, coordinator.warnings);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
424
997
|
}
|
|
998
|
+
/**
|
|
999
|
+
* Internal-surface exports for unit tests in `__tests__/`. Not part of the
|
|
1000
|
+
* public package API — these are intentionally namespaced under `__testing`
|
|
1001
|
+
* so they don't appear in the package's exports surface to downstream
|
|
1002
|
+
* consumers. (They're still importable, but the underscore convention
|
|
1003
|
+
* signals "test only".)
|
|
1004
|
+
*
|
|
1005
|
+
* Exposed:
|
|
1006
|
+
* - `failSoft`: wrap an iterable with the W1.5-01/02 watchdog + soft-isolate.
|
|
1007
|
+
* - `createWedgeCoordinator`: build a coordinator + warnings sink with
|
|
1008
|
+
* optional cap/drain overrides for deterministic tests.
|
|
1009
|
+
* - `drainBackgroundWedge`: run the post-merger late-drain pass against
|
|
1010
|
+
* a single background-wedge entry.
|
|
1011
|
+
* - `mergeAsyncIterablesParallel`: re-export for symmetry; the (array,
|
|
1012
|
+
* opts) overload is what tests use to fix concurrency.
|
|
1013
|
+
* - `setTestWatchdogBudgets` / `resetTestWatchdogBudgets`: env-var-backed
|
|
1014
|
+
* knobs to squeeze the watchdog budget for fast tests. Always paired
|
|
1015
|
+
* via try/finally in tests so the environment is left clean.
|
|
1016
|
+
*/
|
|
1017
|
+
export const __testing = {
|
|
1018
|
+
failSoft,
|
|
1019
|
+
createWedgeCoordinator,
|
|
1020
|
+
drainBackgroundWedge,
|
|
1021
|
+
mergeAsyncIterablesParallel,
|
|
1022
|
+
readWatchdogBudgets,
|
|
1023
|
+
setTestWatchdogBudgets(opts) {
|
|
1024
|
+
process.env.SFGRAPH_WATCHDOG_FIRST_YIELD_MS = String(opts.firstYieldMs);
|
|
1025
|
+
process.env.SFGRAPH_WATCHDOG_INACTIVITY_MS = String(opts.inactivityMs);
|
|
1026
|
+
},
|
|
1027
|
+
resetTestWatchdogBudgets() {
|
|
1028
|
+
// Note: assigning `undefined` to a `process.env.X` key in Node coerces to
|
|
1029
|
+
// the string "undefined". That's fine here because readWatchdogBudgets()
|
|
1030
|
+
// runs parseInt() on the value, parseInt("undefined") === NaN, and NaN
|
|
1031
|
+
// falls through to the *_MS_DEFAULT branch. So semantically equivalent
|
|
1032
|
+
// to `delete`, but satisfies biome's lint/performance/noDelete.
|
|
1033
|
+
process.env.SFGRAPH_WATCHDOG_FIRST_YIELD_MS = undefined;
|
|
1034
|
+
process.env.SFGRAPH_WATCHDOG_INACTIVITY_MS = undefined;
|
|
1035
|
+
},
|
|
1036
|
+
};
|
|
425
1037
|
//# sourceMappingURL=bulk-retrieve.js.map
|