@tearleads/client-sdk 0.1.116 → 0.1.118
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/data/keyingProjectionVerification/checkpoints/checkpointContext.d.ts +8 -1
- package/data/keyingProjectionVerification/checkpoints/checkpointContext.js +15 -0
- package/data/keyingProjectionVerification/checkpoints/checkpointContext.js.map +1 -1
- package/data/keyingProjectionVerification/container/containerProjectionVerification.js +3 -1
- package/data/keyingProjectionVerification/container/containerProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/document/documentProjectionVerification.js +2 -1
- package/data/keyingProjectionVerification/document/documentProjectionVerification.js.map +1 -1
- package/data/persistence/container-contents/containerContentsPersistence.js +14 -13
- package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
- package/data/persistence/documents/internal/ensureDocumentsSchema.js +10 -12
- package/data/persistence/documents/internal/ensureDocumentsSchema.js.map +1 -1
- package/data/persistence/verifiedCitations/citationScope.js +121 -0
- package/data/persistence/verifiedCitations/citationScope.js.map +1 -0
- package/data/persistence/verifiedCitations/kekLevelCitations.d.ts +33 -0
- package/data/persistence/verifiedCitations/kekLevelCitations.js +44 -0
- package/data/persistence/verifiedCitations/kekLevelCitations.js.map +1 -0
- package/data/persistence/verifiedManifestBundlePersistence.d.ts +17 -12
- package/data/persistence/verifiedManifestBundlePersistence.js +75 -104
- package/data/persistence/verifiedManifestBundlePersistence.js.map +1 -1
- package/data/sqlite/schema/containerSchema.d.ts +1 -0
- package/data/sqlite/schema/containerSchema.js +8 -1
- package/data/sqlite/schema/containerSchema.js.map +1 -1
- package/data/sqlite/schema/documentAttachmentSchema.d.ts +0 -2
- package/data/sqlite/schema/documentAttachmentSchema.js +0 -4
- package/data/sqlite/schema/documentAttachmentSchema.js.map +1 -1
- package/data/sqlite/schema/index.d.ts +2 -0
- package/data/sqlite/schema/index.js +10 -1
- package/data/sqlite/schema/index.js.map +1 -1
- package/data/sqlite/schema/principalPolicySchema.js +0 -1
- package/data/sqlite/schema/principalPolicySchema.js.map +1 -1
- package/data/sqlite/schema/verifiedManifestBundleSchema.d.ts +7 -2
- package/data/sqlite/schema/verifiedManifestBundleSchema.js +11 -4
- package/data/sqlite/schema/verifiedManifestBundleSchema.js.map +1 -1
- package/data/sqlite/sqlExec.d.ts +12 -0
- package/data/sqlite/sqlExec.js +47 -3
- package/data/sqlite/sqlExec.js.map +1 -1
- package/data/sqlite/sqlTableSchema.js +40 -15
- package/data/sqlite/sqlTableSchema.js.map +1 -1
- package/data/sqlite/sqlitePersistenceRuntime.js +18 -10
- package/data/sqlite/sqlitePersistenceRuntime.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +3 -2
- package/internal/api-client/ApiClient.js +3 -2
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/index.d.ts +1 -1
- package/internal/api-client/index.js.map +1 -1
- package/internal/api-client/types.d.ts +7 -0
- package/internal/api-client/types.js.map +1 -1
- package/internal/api-client/verifiedManifestCitations.d.ts +26 -9
- package/internal/api-client/verifiedManifestCitations.js +44 -25
- package/internal/api-client/verifiedManifestCitations.js.map +1 -1
- package/internal/api-client/writerProjectionRequests.js +21 -10
- package/internal/api-client/writerProjectionRequests.js.map +1 -1
- package/internal/crypto/index.d.ts +1 -1
- package/internal/crypto/index.js +1 -1
- package/internal/crypto/index.js.map +1 -1
- package/internal/crypto/keying/canonicalJsonGuard.d.ts +7 -0
- package/internal/crypto/keying/canonicalJsonGuard.js +20 -0
- package/internal/crypto/keying/canonicalJsonGuard.js.map +1 -1
- package/internal/crypto/keying/index.d.ts +1 -1
- package/internal/crypto/keying/index.js +1 -1
- package/internal/crypto/keying/index.js.map +1 -1
- package/internal/validators/knownManifestsRefinements.js +1 -1
- package/internal/validators/knownManifestsRefinements.js.map +1 -1
- package/internal/validators/operation/writerProjections.d.ts +42 -18
- package/internal/validators/response/container.d.ts +137 -16
- package/internal/validators/response/container.js +23 -2
- package/internal/validators/response/container.js.map +1 -1
- package/internal/validators/response/documentMutation.d.ts +20 -8
- package/internal/validators/response/index.d.ts +2 -2
- package/internal/validators/response/index.js +2 -2
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/writerProjectionWire.d.ts +19 -8
- package/internal/validators/response/writerProjectionWire.js +78 -20
- package/internal/validators/response/writerProjectionWire.js.map +1 -1
- package/internal/validators/util/index.d.ts +1 -1
- package/internal/validators/util/index.js +1 -1
- package/internal/validators/util/index.js.map +1 -1
- package/internal/validators/util/knownManifestWire.d.ts +13 -3
- package/internal/validators/util/knownManifestWire.js +37 -10
- package/internal/validators/util/knownManifestWire.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/remoteHydration/destination/destinationPrefetch.js +10 -5
- package/workflows/container-contents/remoteHydration/destination/destinationPrefetch.js.map +1 -1
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js +4 -6
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js.map +1 -1
- package/workflows/container-contents/remoteHydration/types.d.ts +2 -2
- package/workflows/container-contents/remoteHydration/types.js.map +1 -1
|
@@ -4,23 +4,50 @@ import { knownManifestsHeaderRefinement } from "../knownManifestsRefinements.js"
|
|
|
4
4
|
import { isSha256HexString, SHA256_HEX_LENGTH } from "./protocol.js";
|
|
5
5
|
/**
|
|
6
6
|
* Hints bound the omission a request can ask for, never the history a reader
|
|
7
|
-
* receives: an uncited manifest always travels.
|
|
7
|
+
* receives: an uncited manifest or KEK level always travels.
|
|
8
8
|
*/
|
|
9
9
|
export const KNOWN_MANIFEST_HINT_LIMIT = 48;
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/** `m:` cites a manifest bundle by hash, `k:` a KEK level by digest. */
|
|
11
|
+
const MANIFEST_HINT_PREFIX = "m:";
|
|
12
|
+
const KEK_LEVEL_HINT_PREFIX = "k:";
|
|
13
|
+
const KNOWN_MANIFEST_HINT_CHARACTERS = KNOWN_MANIFEST_HINT_LIMIT *
|
|
14
|
+
(MANIFEST_HINT_PREFIX.length + SHA256_HEX_LENGTH + 1) -
|
|
15
|
+
1;
|
|
16
|
+
/**
|
|
17
|
+
* Null unless the header is 1–48 unique typed entries, each `m:` or `k:`
|
|
18
|
+
* followed by a lowercase SHA-256 hex digest.
|
|
19
|
+
*/
|
|
12
20
|
export function parseKnownManifestHints(value) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
new Set(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
const entries = value.split(",");
|
|
22
|
+
if (entries.length > KNOWN_MANIFEST_HINT_LIMIT ||
|
|
23
|
+
new Set(entries).size !== entries.length)
|
|
24
|
+
return null;
|
|
25
|
+
const manifests = [];
|
|
26
|
+
const kekLevels = [];
|
|
27
|
+
for (const entry of entries) {
|
|
28
|
+
const digest = entry.slice(MANIFEST_HINT_PREFIX.length);
|
|
29
|
+
if (!isSha256HexString(digest))
|
|
30
|
+
return null;
|
|
31
|
+
if (entry.startsWith(MANIFEST_HINT_PREFIX))
|
|
32
|
+
manifests.push(digest);
|
|
33
|
+
else if (entry.startsWith(KEK_LEVEL_HINT_PREFIX))
|
|
34
|
+
kekLevels.push(digest);
|
|
35
|
+
else
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return { manifests, kekLevels };
|
|
39
|
+
}
|
|
40
|
+
/** The header value for `hints`; callers keep the total within the limit. */
|
|
41
|
+
export function formatKnownManifestHints(hints) {
|
|
42
|
+
return [
|
|
43
|
+
...hints.kekLevels.map((digest) => `${KEK_LEVEL_HINT_PREFIX}${digest}`),
|
|
44
|
+
...hints.manifests.map((hash) => `${MANIFEST_HINT_PREFIX}${hash}`),
|
|
45
|
+
].join(",");
|
|
19
46
|
}
|
|
20
47
|
const hintHeader = registerJsonSchemaFragment(z.string().max(KNOWN_MANIFEST_HINT_CHARACTERS), {
|
|
21
48
|
type: "string",
|
|
22
49
|
maxLength: KNOWN_MANIFEST_HINT_CHARACTERS,
|
|
23
|
-
description: `Comma-separated
|
|
50
|
+
description: `Comma-separated typed digests the device holds verified: m:<manifest hash> for an access-manifest bundle, k:<level digest> for a container KEK level; at most ${KNOWN_MANIFEST_HINT_LIMIT}, unique`,
|
|
24
51
|
});
|
|
25
52
|
export const KnownManifestsHeadersSchema = z.object({
|
|
26
53
|
"x-known-manifests": registerJsonSchemaRuntimeRefinements(hintHeader.refine((value) => parseKnownManifestHints(value) !== null), [knownManifestsHeaderRefinement]).optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knownManifestWire.js","sourceRoot":"","sources":["knownManifestWire.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,0BAA0B,EAC1B,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElE;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAC5C,MAAM,8BAA8B,GAClC,yBAAyB,
|
|
1
|
+
{"version":3,"file":"knownManifestWire.js","sourceRoot":"","sources":["knownManifestWire.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,0BAA0B,EAC1B,oCAAoC,GACrC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElE;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAC5C,wEAAwE;AACxE,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AACnC,MAAM,8BAA8B,GAClC,yBAAyB;IACvB,CAAC,oBAAoB,CAAC,MAAM,GAAG,iBAAiB,GAAG,CAAC,CAAC;IACvD,CAAC,CAAC;AAQJ;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,KAAa;IAEb,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IACE,OAAO,CAAC,MAAM,GAAG,yBAAyB;QAC1C,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM;QAExC,OAAO,IAAI,CAAC;IACd,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,oBAAoB,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;aAC9D,IAAI,KAAK,CAAC,UAAU,CAAC,qBAAqB,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;;YACpE,OAAO,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAClC,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,wBAAwB,CAAC,KAAyB;IAChE,OAAO;QACL,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,qBAAqB,GAAG,MAAM,EAAE,CAAC;QACvE,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,oBAAoB,GAAG,IAAI,EAAE,CAAC;KACnE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,GAAG,0BAA0B,CAC3C,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,8BAA8B,CAAC,EAC9C;IACE,IAAI,EAAE,QAAQ;IACd,SAAS,EAAE,8BAA8B;IACzC,WAAW,EAAE,iKAAiK,yBAAyB,UAAU;CAClN,CACF,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,mBAAmB,EAAE,oCAAoC,CACvD,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,EACrE,CAAC,8BAA8B,CAAC,CACjC,CAAC,QAAQ,EAAE;CACb,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport {\n registerJsonSchemaFragment,\n registerJsonSchemaRuntimeRefinements,\n} from \"../jsonSchema\";\nimport { knownManifestsHeaderRefinement } from \"../knownManifestsRefinements\";\nimport { isSha256HexString, SHA256_HEX_LENGTH } from \"./protocol\";\n\n/**\n * Hints bound the omission a request can ask for, never the history a reader\n * receives: an uncited manifest or KEK level always travels.\n */\nexport const KNOWN_MANIFEST_HINT_LIMIT = 48;\n/** `m:` cites a manifest bundle by hash, `k:` a KEK level by digest. */\nconst MANIFEST_HINT_PREFIX = \"m:\";\nconst KEK_LEVEL_HINT_PREFIX = \"k:\";\nconst KNOWN_MANIFEST_HINT_CHARACTERS =\n KNOWN_MANIFEST_HINT_LIMIT *\n (MANIFEST_HINT_PREFIX.length + SHA256_HEX_LENGTH + 1) -\n 1;\n\n/** The typed digests one request declares held. */\nexport interface KnownManifestHints {\n readonly manifests: readonly string[];\n readonly kekLevels: readonly string[];\n}\n\n/**\n * Null unless the header is 1–48 unique typed entries, each `m:` or `k:`\n * followed by a lowercase SHA-256 hex digest.\n */\nexport function parseKnownManifestHints(\n value: string,\n): KnownManifestHints | null {\n const entries = value.split(\",\");\n if (\n entries.length > KNOWN_MANIFEST_HINT_LIMIT ||\n new Set(entries).size !== entries.length\n )\n return null;\n const manifests: string[] = [];\n const kekLevels: string[] = [];\n for (const entry of entries) {\n const digest = entry.slice(MANIFEST_HINT_PREFIX.length);\n if (!isSha256HexString(digest)) return null;\n if (entry.startsWith(MANIFEST_HINT_PREFIX)) manifests.push(digest);\n else if (entry.startsWith(KEK_LEVEL_HINT_PREFIX)) kekLevels.push(digest);\n else return null;\n }\n return { manifests, kekLevels };\n}\n\n/** The header value for `hints`; callers keep the total within the limit. */\nexport function formatKnownManifestHints(hints: KnownManifestHints): string {\n return [\n ...hints.kekLevels.map((digest) => `${KEK_LEVEL_HINT_PREFIX}${digest}`),\n ...hints.manifests.map((hash) => `${MANIFEST_HINT_PREFIX}${hash}`),\n ].join(\",\");\n}\n\nconst hintHeader = registerJsonSchemaFragment(\n z.string().max(KNOWN_MANIFEST_HINT_CHARACTERS),\n {\n type: \"string\",\n maxLength: KNOWN_MANIFEST_HINT_CHARACTERS,\n description: `Comma-separated typed digests the device holds verified: m:<manifest hash> for an access-manifest bundle, k:<level digest> for a container KEK level; at most ${KNOWN_MANIFEST_HINT_LIMIT}, unique`,\n },\n);\n\nexport const KnownManifestsHeadersSchema = z.object({\n \"x-known-manifests\": registerJsonSchemaRuntimeRefinements(\n hintHeader.refine((value) => parseKnownManifestHints(value) !== null),\n [knownManifestsHeaderRefinement],\n ).optional(),\n});\n"]}
|
package/package.json
CHANGED
|
@@ -3,16 +3,21 @@ const DESTINATION_PREFETCH_CONCURRENCY = 4;
|
|
|
3
3
|
* Fetch the writer projections of newly discovered folders with bounded
|
|
4
4
|
* concurrency, so a fresh device does not pay one round trip per folder in
|
|
5
5
|
* series. Verification stays sequential and consumes these results. A failed
|
|
6
|
-
* fetch is omitted: verification refetches and reports it.
|
|
6
|
+
* fetch is omitted: verification refetches and reports it. Each folder's
|
|
7
|
+
* listing places it for citation, since its row is not stored yet: the read
|
|
8
|
+
* cites the listed parent's held bytes.
|
|
7
9
|
*/
|
|
8
10
|
export async function prefetchDestinationProjections(input) {
|
|
9
11
|
const prefetched = new Map();
|
|
10
|
-
const pending = [...input.
|
|
12
|
+
const pending = [...input.containers];
|
|
11
13
|
const fetchNext = async () => {
|
|
12
|
-
for (let
|
|
14
|
+
for (let container = pending.shift(); container !== undefined && input.isCurrent?.() !== false; container = pending.shift()) {
|
|
13
15
|
try {
|
|
14
|
-
prefetched.set(
|
|
15
|
-
projection: await input.runtime.apiClient.getContainerWriterProjection(
|
|
16
|
+
prefetched.set(container.id, {
|
|
17
|
+
projection: await input.runtime.apiClient.getContainerWriterProjection(container.id, {
|
|
18
|
+
organizationId: container.organizationId,
|
|
19
|
+
parentId: container.parentId,
|
|
20
|
+
}),
|
|
16
21
|
});
|
|
17
22
|
}
|
|
18
23
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"destinationPrefetch.js","sourceRoot":"","sources":["destinationPrefetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"destinationPrefetch.js","sourceRoot":"","sources":["destinationPrefetch.ts"],"names":[],"mappings":"AASA,MAAM,gCAAgC,GAAG,CAAC,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAIpD;IACC,MAAM,UAAU,GAAG,IAAI,GAAG,EAA2C,CAAC;IACtE,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,KAAK,IAAmB,EAAE;QAC1C,KACE,IAAI,SAAS,GAAG,OAAO,CAAC,KAAK,EAAE,EAC/B,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,KAAK,KAAK,EACxD,SAAS,GAAG,OAAO,CAAC,KAAK,EAAE,EAC3B,CAAC;YACD,IAAI,CAAC;gBACH,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,EAAE;oBAC3B,UAAU,EACR,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,4BAA4B,CACxD,SAAS,CAAC,EAAE,EACZ;wBACE,cAAc,EAAE,SAAS,CAAC,cAAc;wBACxC,QAAQ,EAAE,SAAS,CAAC,QAAQ;qBAC7B,CACF;iBACJ,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,8DAA8D;YAChE,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CACR,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,gCAAgC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,EACtE,SAAS,CACV,CACF,CAAC;IACF,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["import type { WriterProjectionListing } from \"@tearleads/api-client\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { RemoteContainerHydrationState } from \"../types\";\n\n/** A projection fetched ahead of sequential verification. */\nexport interface PrefetchedDestinationProjection {\n readonly projection: ContainerWriterProjectionResponse | null;\n}\n\nconst DESTINATION_PREFETCH_CONCURRENCY = 4;\n\n/**\n * Fetch the writer projections of newly discovered folders with bounded\n * concurrency, so a fresh device does not pay one round trip per folder in\n * series. Verification stays sequential and consumes these results. A failed\n * fetch is omitted: verification refetches and reports it. Each folder's\n * listing places it for citation, since its row is not stored yet: the read\n * cites the listed parent's held bytes.\n */\nexport async function prefetchDestinationProjections(input: {\n containers: ReadonlyArray<{ readonly id: string } & WriterProjectionListing>;\n isCurrent?: (() => boolean) | undefined;\n runtime: RemoteContainerHydrationState[\"runtime\"];\n}): Promise<ReadonlyMap<string, PrefetchedDestinationProjection>> {\n const prefetched = new Map<string, PrefetchedDestinationProjection>();\n const pending = [...input.containers];\n const fetchNext = async (): Promise<void> => {\n for (\n let container = pending.shift();\n container !== undefined && input.isCurrent?.() !== false;\n container = pending.shift()\n ) {\n try {\n prefetched.set(container.id, {\n projection:\n await input.runtime.apiClient.getContainerWriterProjection(\n container.id,\n {\n organizationId: container.organizationId,\n parentId: container.parentId,\n },\n ),\n });\n } catch {\n // Verification refetches this folder and reports the failure.\n }\n }\n };\n await Promise.all(\n Array.from(\n { length: Math.min(DESTINATION_PREFETCH_CONCURRENCY, pending.length) },\n fetchNext,\n ),\n );\n return prefetched;\n}\n"]}
|
|
@@ -40,12 +40,10 @@ async function applyRemoteContainerPage(input) {
|
|
|
40
40
|
return { changedCount: 0, completed: false };
|
|
41
41
|
}
|
|
42
42
|
const prefetchedProjections = await prefetchDestinationProjections({
|
|
43
|
-
|
|
44
|
-
state.containersById.has(item.id)
|
|
45
|
-
expectedHydrationTombstones.get(item.id)
|
|
46
|
-
cachedDestinationRole(state.runtime.infra.execSql, item)
|
|
47
|
-
? []
|
|
48
|
-
: [item.id]),
|
|
43
|
+
containers: items.filter((item) => !seenContainerIds.has(item.id) &&
|
|
44
|
+
!state.containersById.has(item.id) &&
|
|
45
|
+
!expectedHydrationTombstones.get(item.id) &&
|
|
46
|
+
!cachedDestinationRole(state.runtime.infra.execSql, item)),
|
|
49
47
|
isCurrent: input.isCurrent,
|
|
50
48
|
runtime: state.runtime,
|
|
51
49
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteContainerPageHydration.js","sourceRoot":"","sources":["remoteContainerPageHydration.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createPrincipalPolicyOperation,\n createRuntimePrincipalPolicyWarmer,\n type PrincipalPolicyOperation,\n} from \"../../../principals/runtimePolicyWarmer\";\nimport { prefetchDestinationProjections } from \"../destination/destinationPrefetch\";\nimport { cachedDestinationRole } from \"../destination/destinationRoleCache\";\nimport { markContainerParentLaneFetched } from \"../lanes/laneFetchMarkers\";\nimport { fetchContainerParentLaneBatch } from \"../lanes/parentLaneFetch\";\nimport { cacheRemoteContainerPrincipalPolicies } from \"../principalPolicyCache\";\nimport {\n applyContainerTombstones,\n getApplicableRemoteContainerItems,\n} from \"../tombstoneApplication\";\nimport type {\n ContainerChildIndex,\n ContainerParentHydrationLane,\n ExpectedContainerState,\n FetchedContainerParentLanePage,\n ListedRemoteContainerPageItem,\n QueueContainerParentLane,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"../types\";\nimport { containerStateMatchesFingerprint } from \"./containerStateFingerprint\";\nimport { loadPausedContainerFilter } from \"./organizationSyncPauseFilter\";\nimport {\n listRemoteContainerIdsWithPendingMetadataUpdates,\n listRemoteContainerIdsWithPendingStructuralIntents,\n upsertIsolatedRemoteContainerState,\n} from \"./remoteContainerState\";\n\nconst CONTAINER_PARENT_HYDRATION_CONCURRENCY = 4;\n\ninterface HydrationProgress {\n changedCount: number;\n complete: boolean;\n shouldStop: boolean;\n}\n// Re-checked inside the commit: a pause from another device can land after\n// the page was filtered, and its cleanup may already have run.\nfunction currentUnlessPaused(\n input: {\n isCurrent?: (() => boolean) | undefined;\n isPaused: (container: ListedRemoteContainerPageItem) => boolean;\n },\n container: ListedRemoteContainerPageItem,\n): () => boolean {\n return () => input.isCurrent?.() !== false && !input.isPaused(container);\n}\n\nasync function applyRemoteContainerPage(input: {\n childIdsByParentId: ContainerChildIndex;\n expectedContainerStates: ReadonlyMap<string, ExpectedContainerState>;\n expectedHydrationTombstones: FetchedContainerParentLanePage[\"expectedHydrationTombstones\"];\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n /** Live pause check; a pause arriving mid-page stops the commit. */\n isPaused: (container: ListedRemoteContainerPageItem) => boolean;\n items: ReadonlyArray<ListedRemoteContainerPageItem>;\n /** The hydration pass's token: its pages share one directory discovery. */\n policyOperation: PrincipalPolicyOperation;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<{ changedCount: number; completed: boolean }> {\n const {\n childIdsByParentId,\n expectedContainerStates,\n expectedHydrationTombstones,\n host,\n items,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let hydratedCount = 0;\n let pageCompleted = true;\n await cacheRemoteContainerPrincipalPolicies({\n cacheReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n state.runtime,\n { operation: input.policyOperation },\n ),\n remoteContainers: items,\n stillCurrent: input.isCurrent,\n });\n if (input.isCurrent?.() === false) {\n return { changedCount: 0, completed: false };\n }\n const [\n containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents,\n ] = await Promise.all([\n listRemoteContainerIdsWithPendingMetadataUpdates({\n remoteContainers: items,\n state,\n }),\n listRemoteContainerIdsWithPendingStructuralIntents({\n remoteContainers: items,\n state,\n }),\n ]);\n if (input.isCurrent?.() === false) {\n return { changedCount: 0, completed: false };\n }\n const prefetchedProjections = await prefetchDestinationProjections({\n containerIds: items.flatMap((item) =>\n seenContainerIds.has(item.id) ||\n state.containersById.has(item.id) ||\n expectedHydrationTombstones.get(item.id) ||\n cachedDestinationRole(state.runtime.infra.execSql, item)\n ? []\n : [item.id],\n ),\n isCurrent: input.isCurrent,\n runtime: state.runtime,\n });\n for (const container of items) {\n if (input.isCurrent?.() === false) {\n return { changedCount: hydratedCount, completed: false };\n }\n if (!seenContainerIds.has(container.id)) {\n if (\n !containerStateMatchesFingerprint({\n currentState: state.containersById.get(container.id),\n expectedFingerprint: expectedContainerStates.get(container.id)\n ?.fingerprint,\n })\n ) {\n pageCompleted = false;\n continue;\n }\n const upserted = await upsertIsolatedRemoteContainerState({\n childIdsByParentId,\n containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents,\n host,\n isCurrent: currentUnlessPaused(input, container),\n expectedHydrationTombstone:\n expectedHydrationTombstones.get(container.id) ?? null,\n prefetchedProjection: prefetchedProjections.get(container.id),\n remoteContainer: container,\n state,\n });\n if (!upserted) {\n pageCompleted = false;\n continue;\n }\n seenContainerIds.add(container.id);\n hydratedCount += 1;\n if (input.isCurrent?.() === false) {\n return { changedCount: hydratedCount, completed: false };\n }\n }\n queueParentLane(container.id);\n }\n\n return { changedCount: hydratedCount, completed: pageCompleted };\n}\n\nexport function canHydrateRemoteContainers(\n state: RemoteContainerHydrationState,\n): boolean {\n return (\n state.runtime.auth.isAuthenticated &&\n state.runtime.state.online &&\n state.runtime.infra.dbStatus === \"ready\"\n );\n}\n\nasync function applyContainerParentLanePage(input: {\n childIdsByParentId: ContainerChildIndex;\n fetchedPage: FetchedContainerParentLanePage;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n policyOperation: PrincipalPolicyOperation;\n queueContinuationLane: (lane: ContainerParentHydrationLane) => void;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n fetchedPage,\n host,\n queueContinuationLane,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n const {\n expectedContainerStates,\n expectedHydrationTombstones,\n lane,\n response,\n syncLane,\n } = fetchedPage;\n let changedCount = 0;\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const remoteContainerItems = getApplicableRemoteContainerItems(response);\n const tombstoneResult = await applyContainerTombstones({\n childIdsByParentId,\n expectedContainerStates,\n isCurrent: input.isCurrent,\n remoteContainerItems,\n response,\n state,\n });\n if (!tombstoneResult.current) {\n return { changedCount, complete: false, shouldStop: true };\n }\n changedCount += tombstoneResult.changedCount;\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (tombstoneResult.changedCount > 0) {\n // A live tombstone cascade may have orphaned documents (row 3); re-arm\n // document priming so their null-scoped passes run now rather than on\n // the next startup.\n host.requestDocumentPriming?.();\n }\n\n // A paused organization's containers stay off the device. Skipping them\n // here, after tombstones saw the full page, still lets the lane complete\n // and its watermark advance; their children are never queued.\n const isPaused = await loadPausedContainerFilter(state);\n const appliedPage = await applyRemoteContainerPage({\n childIdsByParentId,\n expectedContainerStates,\n expectedHydrationTombstones,\n host,\n isCurrent: input.isCurrent,\n isPaused,\n items: remoteContainerItems.filter((item) => !isPaused(item)),\n policyOperation: input.policyOperation,\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += appliedPage.changedCount;\n if (!tombstoneResult.completed || !appliedPage.completed) {\n // Keep this page retryable without discarding independent lanes, including\n // children of roots first discovered here. Otherwise the root becomes known\n // but its children are never fetched by subsequent root-only refreshes.\n return { changedCount, complete: false, shouldStop: false };\n }\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const didMarkFetched = await markContainerParentLaneFetched({\n isCurrent: input.isCurrent,\n response,\n state,\n syncLane,\n });\n if (!didMarkFetched) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n if (!response.hasMore) {\n return { changedCount, complete: true, shouldStop: false };\n }\n if (!response.nextWatermark) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n queueContinuationLane({\n parentId: lane.parentId,\n watermark: response.nextWatermark,\n });\n return { changedCount, complete: true, shouldStop: false };\n}\n\nfunction takeContainerParentLaneBatch(input: {\n lanes: ContainerParentHydrationLane[];\n state: RemoteContainerHydrationState;\n}): ContainerParentHydrationLane[] {\n const { lanes, state } = input;\n const batch: ContainerParentHydrationLane[] = [];\n\n while (\n lanes.length > 0 &&\n batch.length < CONTAINER_PARENT_HYDRATION_CONCURRENCY\n ) {\n const lane = lanes.shift();\n if (\n lane &&\n (lane.parentId === null || state.containersById.has(lane.parentId))\n ) {\n batch.push(lane);\n }\n }\n\n return batch;\n}\n\nasync function applyContainerParentLaneBatch(input: {\n childIdsByParentId: ContainerChildIndex;\n fetchedPages: ReadonlyArray<FetchedContainerParentLanePage>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n lanes: ContainerParentHydrationLane[];\n policyOperation: PrincipalPolicyOperation;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n fetchedPages,\n host,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let changedCount = 0;\n let complete = true;\n\n for (const fetchedPage of fetchedPages) {\n if (!canHydrateRemoteContainers(state) || input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (\n fetchedPage.lane.parentId !== null &&\n !state.containersById.has(fetchedPage.lane.parentId)\n ) {\n continue;\n }\n\n const result = await applyContainerParentLanePage({\n childIdsByParentId,\n fetchedPage,\n host,\n isCurrent: input.isCurrent,\n policyOperation: input.policyOperation,\n queueContinuationLane: (lane) => lanes.push(lane),\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += result.changedCount;\n complete &&= result.complete;\n\n if (result.shouldStop) {\n return { changedCount, complete: false, shouldStop: true };\n }\n }\n\n return { changedCount, complete, shouldStop: false };\n}\n\nexport async function hydrateContainerParentLanes(input: {\n childIdsByParentId: ContainerChildIndex;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n lanes: ContainerParentHydrationLane[];\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n host,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let changedCount = 0;\n let complete = true;\n // One hydration pass is one policy operation: its pages share a discovery.\n const policyOperation = createPrincipalPolicyOperation();\n\n while (lanes.length > 0) {\n if (!canHydrateRemoteContainers(state) || input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const batch = takeContainerParentLaneBatch({ lanes, state });\n if (batch.length === 0) {\n continue;\n }\n\n const fetchedPages = await fetchContainerParentLaneBatch({\n batch,\n isCurrent: input.isCurrent,\n state,\n });\n if (!fetchedPages) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const result = await applyContainerParentLaneBatch({\n childIdsByParentId,\n fetchedPages,\n host,\n isCurrent: input.isCurrent,\n lanes,\n policyOperation,\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += result.changedCount;\n complete &&= result.complete;\n\n if (result.shouldStop) {\n return { changedCount, complete: false, shouldStop: true };\n }\n }\n\n return { changedCount, complete, shouldStop: false };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteContainerPageHydration.js","sourceRoot":"","sources":["remoteContainerPageHydration.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createPrincipalPolicyOperation,\n createRuntimePrincipalPolicyWarmer,\n type PrincipalPolicyOperation,\n} from \"../../../principals/runtimePolicyWarmer\";\nimport { prefetchDestinationProjections } from \"../destination/destinationPrefetch\";\nimport { cachedDestinationRole } from \"../destination/destinationRoleCache\";\nimport { markContainerParentLaneFetched } from \"../lanes/laneFetchMarkers\";\nimport { fetchContainerParentLaneBatch } from \"../lanes/parentLaneFetch\";\nimport { cacheRemoteContainerPrincipalPolicies } from \"../principalPolicyCache\";\nimport {\n applyContainerTombstones,\n getApplicableRemoteContainerItems,\n} from \"../tombstoneApplication\";\nimport type {\n ContainerChildIndex,\n ContainerParentHydrationLane,\n ExpectedContainerState,\n FetchedContainerParentLanePage,\n ListedRemoteContainerPageItem,\n QueueContainerParentLane,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"../types\";\nimport { containerStateMatchesFingerprint } from \"./containerStateFingerprint\";\nimport { loadPausedContainerFilter } from \"./organizationSyncPauseFilter\";\nimport {\n listRemoteContainerIdsWithPendingMetadataUpdates,\n listRemoteContainerIdsWithPendingStructuralIntents,\n upsertIsolatedRemoteContainerState,\n} from \"./remoteContainerState\";\n\nconst CONTAINER_PARENT_HYDRATION_CONCURRENCY = 4;\n\ninterface HydrationProgress {\n changedCount: number;\n complete: boolean;\n shouldStop: boolean;\n}\n// Re-checked inside the commit: a pause from another device can land after\n// the page was filtered, and its cleanup may already have run.\nfunction currentUnlessPaused(\n input: {\n isCurrent?: (() => boolean) | undefined;\n isPaused: (container: ListedRemoteContainerPageItem) => boolean;\n },\n container: ListedRemoteContainerPageItem,\n): () => boolean {\n return () => input.isCurrent?.() !== false && !input.isPaused(container);\n}\n\nasync function applyRemoteContainerPage(input: {\n childIdsByParentId: ContainerChildIndex;\n expectedContainerStates: ReadonlyMap<string, ExpectedContainerState>;\n expectedHydrationTombstones: FetchedContainerParentLanePage[\"expectedHydrationTombstones\"];\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n /** Live pause check; a pause arriving mid-page stops the commit. */\n isPaused: (container: ListedRemoteContainerPageItem) => boolean;\n items: ReadonlyArray<ListedRemoteContainerPageItem>;\n /** The hydration pass's token: its pages share one directory discovery. */\n policyOperation: PrincipalPolicyOperation;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<{ changedCount: number; completed: boolean }> {\n const {\n childIdsByParentId,\n expectedContainerStates,\n expectedHydrationTombstones,\n host,\n items,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let hydratedCount = 0;\n let pageCompleted = true;\n await cacheRemoteContainerPrincipalPolicies({\n cacheReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n state.runtime,\n { operation: input.policyOperation },\n ),\n remoteContainers: items,\n stillCurrent: input.isCurrent,\n });\n if (input.isCurrent?.() === false) {\n return { changedCount: 0, completed: false };\n }\n const [\n containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents,\n ] = await Promise.all([\n listRemoteContainerIdsWithPendingMetadataUpdates({\n remoteContainers: items,\n state,\n }),\n listRemoteContainerIdsWithPendingStructuralIntents({\n remoteContainers: items,\n state,\n }),\n ]);\n if (input.isCurrent?.() === false) {\n return { changedCount: 0, completed: false };\n }\n const prefetchedProjections = await prefetchDestinationProjections({\n containers: items.filter(\n (item) =>\n !seenContainerIds.has(item.id) &&\n !state.containersById.has(item.id) &&\n !expectedHydrationTombstones.get(item.id) &&\n !cachedDestinationRole(state.runtime.infra.execSql, item),\n ),\n isCurrent: input.isCurrent,\n runtime: state.runtime,\n });\n for (const container of items) {\n if (input.isCurrent?.() === false) {\n return { changedCount: hydratedCount, completed: false };\n }\n if (!seenContainerIds.has(container.id)) {\n if (\n !containerStateMatchesFingerprint({\n currentState: state.containersById.get(container.id),\n expectedFingerprint: expectedContainerStates.get(container.id)\n ?.fingerprint,\n })\n ) {\n pageCompleted = false;\n continue;\n }\n const upserted = await upsertIsolatedRemoteContainerState({\n childIdsByParentId,\n containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents,\n host,\n isCurrent: currentUnlessPaused(input, container),\n expectedHydrationTombstone:\n expectedHydrationTombstones.get(container.id) ?? null,\n prefetchedProjection: prefetchedProjections.get(container.id),\n remoteContainer: container,\n state,\n });\n if (!upserted) {\n pageCompleted = false;\n continue;\n }\n seenContainerIds.add(container.id);\n hydratedCount += 1;\n if (input.isCurrent?.() === false) {\n return { changedCount: hydratedCount, completed: false };\n }\n }\n queueParentLane(container.id);\n }\n\n return { changedCount: hydratedCount, completed: pageCompleted };\n}\n\nexport function canHydrateRemoteContainers(\n state: RemoteContainerHydrationState,\n): boolean {\n return (\n state.runtime.auth.isAuthenticated &&\n state.runtime.state.online &&\n state.runtime.infra.dbStatus === \"ready\"\n );\n}\n\nasync function applyContainerParentLanePage(input: {\n childIdsByParentId: ContainerChildIndex;\n fetchedPage: FetchedContainerParentLanePage;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n policyOperation: PrincipalPolicyOperation;\n queueContinuationLane: (lane: ContainerParentHydrationLane) => void;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n fetchedPage,\n host,\n queueContinuationLane,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n const {\n expectedContainerStates,\n expectedHydrationTombstones,\n lane,\n response,\n syncLane,\n } = fetchedPage;\n let changedCount = 0;\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const remoteContainerItems = getApplicableRemoteContainerItems(response);\n const tombstoneResult = await applyContainerTombstones({\n childIdsByParentId,\n expectedContainerStates,\n isCurrent: input.isCurrent,\n remoteContainerItems,\n response,\n state,\n });\n if (!tombstoneResult.current) {\n return { changedCount, complete: false, shouldStop: true };\n }\n changedCount += tombstoneResult.changedCount;\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (tombstoneResult.changedCount > 0) {\n // A live tombstone cascade may have orphaned documents (row 3); re-arm\n // document priming so their null-scoped passes run now rather than on\n // the next startup.\n host.requestDocumentPriming?.();\n }\n\n // A paused organization's containers stay off the device. Skipping them\n // here, after tombstones saw the full page, still lets the lane complete\n // and its watermark advance; their children are never queued.\n const isPaused = await loadPausedContainerFilter(state);\n const appliedPage = await applyRemoteContainerPage({\n childIdsByParentId,\n expectedContainerStates,\n expectedHydrationTombstones,\n host,\n isCurrent: input.isCurrent,\n isPaused,\n items: remoteContainerItems.filter((item) => !isPaused(item)),\n policyOperation: input.policyOperation,\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += appliedPage.changedCount;\n if (!tombstoneResult.completed || !appliedPage.completed) {\n // Keep this page retryable without discarding independent lanes, including\n // children of roots first discovered here. Otherwise the root becomes known\n // but its children are never fetched by subsequent root-only refreshes.\n return { changedCount, complete: false, shouldStop: false };\n }\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const didMarkFetched = await markContainerParentLaneFetched({\n isCurrent: input.isCurrent,\n response,\n state,\n syncLane,\n });\n if (!didMarkFetched) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n if (!response.hasMore) {\n return { changedCount, complete: true, shouldStop: false };\n }\n if (!response.nextWatermark) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n queueContinuationLane({\n parentId: lane.parentId,\n watermark: response.nextWatermark,\n });\n return { changedCount, complete: true, shouldStop: false };\n}\n\nfunction takeContainerParentLaneBatch(input: {\n lanes: ContainerParentHydrationLane[];\n state: RemoteContainerHydrationState;\n}): ContainerParentHydrationLane[] {\n const { lanes, state } = input;\n const batch: ContainerParentHydrationLane[] = [];\n\n while (\n lanes.length > 0 &&\n batch.length < CONTAINER_PARENT_HYDRATION_CONCURRENCY\n ) {\n const lane = lanes.shift();\n if (\n lane &&\n (lane.parentId === null || state.containersById.has(lane.parentId))\n ) {\n batch.push(lane);\n }\n }\n\n return batch;\n}\n\nasync function applyContainerParentLaneBatch(input: {\n childIdsByParentId: ContainerChildIndex;\n fetchedPages: ReadonlyArray<FetchedContainerParentLanePage>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n lanes: ContainerParentHydrationLane[];\n policyOperation: PrincipalPolicyOperation;\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n fetchedPages,\n host,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let changedCount = 0;\n let complete = true;\n\n for (const fetchedPage of fetchedPages) {\n if (!canHydrateRemoteContainers(state) || input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (\n fetchedPage.lane.parentId !== null &&\n !state.containersById.has(fetchedPage.lane.parentId)\n ) {\n continue;\n }\n\n const result = await applyContainerParentLanePage({\n childIdsByParentId,\n fetchedPage,\n host,\n isCurrent: input.isCurrent,\n policyOperation: input.policyOperation,\n queueContinuationLane: (lane) => lanes.push(lane),\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += result.changedCount;\n complete &&= result.complete;\n\n if (result.shouldStop) {\n return { changedCount, complete: false, shouldStop: true };\n }\n }\n\n return { changedCount, complete, shouldStop: false };\n}\n\nexport async function hydrateContainerParentLanes(input: {\n childIdsByParentId: ContainerChildIndex;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n lanes: ContainerParentHydrationLane[];\n queueParentLane: QueueContainerParentLane;\n seenContainerIds: Set<string>;\n state: RemoteContainerHydrationState;\n}): Promise<HydrationProgress> {\n const {\n childIdsByParentId,\n host,\n lanes,\n queueParentLane,\n seenContainerIds,\n state,\n } = input;\n let changedCount = 0;\n let complete = true;\n // One hydration pass is one policy operation: its pages share a discovery.\n const policyOperation = createPrincipalPolicyOperation();\n\n while (lanes.length > 0) {\n if (!canHydrateRemoteContainers(state) || input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const batch = takeContainerParentLaneBatch({ lanes, state });\n if (batch.length === 0) {\n continue;\n }\n\n const fetchedPages = await fetchContainerParentLaneBatch({\n batch,\n isCurrent: input.isCurrent,\n state,\n });\n if (!fetchedPages) {\n return { changedCount, complete: false, shouldStop: true };\n }\n if (input.isCurrent?.() === false) {\n return { changedCount, complete: false, shouldStop: true };\n }\n\n const result = await applyContainerParentLaneBatch({\n childIdsByParentId,\n fetchedPages,\n host,\n isCurrent: input.isCurrent,\n lanes,\n policyOperation,\n queueParentLane,\n seenContainerIds,\n state,\n });\n changedCount += result.changedCount;\n complete &&= result.complete;\n\n if (result.shouldStop) {\n return { changedCount, complete: false, shouldStop: true };\n }\n }\n\n return { changedCount, complete, shouldStop: false };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RequestResult } from "../../../internal/api-client/index.js";
|
|
1
|
+
import type { RequestResult, WriterProjectionListing } from "../../../internal/api-client/index.js";
|
|
2
2
|
import type { ContainerReplacementAuthorizationsResponse } from "../../../internal/validators/operation/index.js";
|
|
3
3
|
import type { ListContainerParentLanesRequest } from "../../../internal/validators/request/index.js";
|
|
4
4
|
import type { ContainerSummary, ContainerWriterProjectionResponse, DocumentWriterProjectionResponse, ListContainerParentLanesResponse, ListContainersResponse, ReferencedPrincipalStateResponse } from "../../../internal/validators/response/index.js";
|
|
@@ -36,7 +36,7 @@ interface RemoteContainerHydrationApi extends Partial<PrincipalPolicyHistoryRead
|
|
|
36
36
|
getContainerReplacementAuthorizationsResult(containerId: string, replacesOrganizationId: string): Promise<RequestResult<ContainerReplacementAuthorizationsResponse>>;
|
|
37
37
|
evictContainerWriterProjection(containerId: string): void;
|
|
38
38
|
evictWriterProjectionsCiting(containerIds: readonly string[]): void;
|
|
39
|
-
getContainerWriterProjection(containerId: string): Promise<ContainerWriterProjectionResponse | null>;
|
|
39
|
+
getContainerWriterProjection(containerId: string, listing?: WriterProjectionListing): Promise<ContainerWriterProjectionResponse | null>;
|
|
40
40
|
listContainerParentLanes(input: ListContainerParentLanesRequest): Promise<ListContainerParentLanesResponse | null>;
|
|
41
41
|
}
|
|
42
42
|
interface RemoteContainerHydrationRuntime extends Pick<ContainerContentsWorkflowRuntime, "auth" | "adoptRootContainer" | "crypto" | "infra" | "resolveTrustedUserIdentity" | "state" | "util"> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n RequestResult,\n WriterProjectionListing,\n} from \"@tearleads/api-client\";\nimport type { ContainerReplacementAuthorizationsResponse } from \"@tearleads/validators/operation\";\nimport type { ListContainerParentLanesRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerSummary,\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n ListContainerParentLanesResponse,\n ListContainersResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { CurrentPrincipalPolicyReader } from \"../../principals/currentPrincipalPolicyReader\";\nimport type { PrincipalPolicyHistoryReader } from \"../../principals/principalPolicyHistoryReader\";\nimport type {\n ContainerContentsPersistence,\n ContainerDocumentRecord,\n ContainerHydrationTombstone,\n ContainerRecord,\n createContainerParentSyncLane,\n} from \"../containerPersistence\";\nimport type { ContainerMetadataPatch } from \"../metadata\";\nimport type { createContainerMetadataDocument } from \"../metadata/containerMetadataDocument\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport type ListedRemoteContainerPageItem =\n ListContainersResponse[\"items\"][number];\nexport type ContainerChildIndex = Map<string, Set<string>>;\nexport type QueueContainerParentLane = (parentId: string | null) => void;\nexport type RemoteContainerIngestQueue = Map<string, RemoteContainer>;\nexport type SaveContainerOptions = Parameters<\n ContainerContentsPersistence[\"saveContainer\"]\n>[3];\n\nexport type ContainerMetadataDocumentState = Awaited<\n ReturnType<typeof createContainerMetadataDocument>\n>;\nexport type RemoteContainer = Pick<\n ContainerSummary,\n | \"createdAt\"\n | \"effectiveAccessLevel\"\n | \"systemSlot\"\n | \"id\"\n | \"metadataAccessEpoch\"\n | \"metadataAccessStateHash\"\n | \"metadataDocumentId\"\n | \"metadataReferencedPrincipals\"\n | \"organizationId\"\n | \"parentId\"\n | \"updatedAt\"\n>;\n\nexport interface ContainerState {\n containerWriterProjection?:\n | ContainerWriterProjectionResponse\n | null\n | undefined;\n /**\n * Bumped whenever a realtime hint or a pull drops this container's cached writer\n * projections (container and metadata document alike); an operation that\n * fetched or carried a projection installs it only if this is unchanged\n * since it started, so a pre-hint answer never lands after the hint.\n */\n writerProjectionGeneration?: number | undefined;\n metadataReferencedPrincipals?:\n | readonly ReferencedPrincipalStateResponse[]\n | undefined;\n container: ContainerRecord;\n doc: ContainerMetadataDocumentState;\n metadataWriterProjection?:\n | DocumentWriterProjectionResponse\n | null\n | undefined;\n /** Durable pull progress mirrored from the metadata document record. */\n pullContinuation?: ContainerDocumentRecord[\"pullContinuation\"] | undefined;\n record: ContainerDocumentRecord;\n}\n\ninterface RemoteContainerHydrationApi\n extends Partial<PrincipalPolicyHistoryReader>,\n CurrentPrincipalPolicyReader {\n getContainerReplacementAuthorizationsResult(\n containerId: string,\n replacesOrganizationId: string,\n ): Promise<RequestResult<ContainerReplacementAuthorizationsResponse>>;\n evictContainerWriterProjection(containerId: string): void;\n evictWriterProjectionsCiting(containerIds: readonly string[]): void;\n getContainerWriterProjection(\n containerId: string,\n listing?: WriterProjectionListing,\n ): Promise<ContainerWriterProjectionResponse | null>;\n listContainerParentLanes(\n input: ListContainerParentLanesRequest,\n ): Promise<ListContainerParentLanesResponse | null>;\n}\n\ninterface RemoteContainerHydrationRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"adoptRootContainer\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n apiClient: RemoteContainerHydrationApi;\n}\n\nexport interface RemoteContainerHydrationState {\n containersById: Map<string, ContainerState>;\n lifecycleGeneration?: number | undefined;\n persistence: ContainerContentsPersistence;\n rootLaneHydrated?: boolean | undefined;\n runtime: RemoteContainerHydrationRuntime;\n structuralGeneration?: number | undefined;\n}\n\nexport type PersistContainerStateResult =\n | { status: \"identity-superseded\"; record: ContainerDocumentRecord }\n | { status: \"missing\" }\n | {\n status: \"persisted\";\n record: ContainerDocumentRecord;\n createIntentSettled?: true | undefined;\n moveIntentSettled?: true | undefined;\n }\n | { status: \"stale-generation\" };\n\nexport interface RemoteContainerHydrationHost {\n persistContainerState: (\n containerState: ContainerState,\n patch?: Partial<ContainerMetadataPatch>,\n updateView?: boolean,\n saveOptions?: SaveContainerOptions,\n mutationOptions?: {\n /** Queued metadata rows the server committed, settled in this write. */\n acceptedPendingUpdateIds?: readonly string[] | undefined;\n clearSyncFailure?: boolean | undefined;\n expectedStateWhenMissing?: ContainerState | undefined;\n isCurrent?: (() => boolean) | undefined;\n createIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"createIntentSettlement\"];\n moveIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"moveIntentSettlement\"];\n preserveDurableStructureWhenPending?: boolean | undefined;\n },\n ) => Promise<PersistContainerStateResult>;\n requestDocumentPriming?: (() => void) | undefined;\n updateSnapshot: () => void;\n}\n\nexport interface ContainerParentHydrationLane {\n parentId: string | null;\n watermark?: ListContainersResponse[\"nextWatermark\"];\n}\n\nexport interface ExpectedContainerState {\n container: ContainerRecord;\n fingerprint: string;\n}\n\nexport interface FetchedContainerParentLanePage {\n expectedContainerStates: ReadonlyMap<string, ExpectedContainerState>;\n expectedHydrationTombstones: ReadonlyMap<string, ContainerHydrationTombstone>;\n lane: ContainerParentHydrationLane;\n response: ListContainersResponse;\n syncLane: ReturnType<typeof createContainerParentSyncLane>;\n}\n"]}
|