agl 1.0.17 → 21.0.2
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/.smartconfig.json +55 -0
- package/changelog.md +1026 -0
- package/cli.js +14 -0
- package/dist_serve/bundle.js +44778 -0
- package/dist_serve/index.html +13 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.authmodels.d.ts +126 -0
- package/dist_ts/classes.authmodels.js +1422 -0
- package/dist_ts/classes.authstore.d.ts +160 -0
- package/dist_ts/classes.authstore.js +2483 -0
- package/dist_ts/classes.browserresourcehost.d.ts +85 -0
- package/dist_ts/classes.browserresourcehost.js +912 -0
- package/dist_ts/classes.cli.d.ts +21 -0
- package/dist_ts/classes.cli.js +1082 -0
- package/dist_ts/classes.config.d.ts +23 -0
- package/dist_ts/classes.config.js +267 -0
- package/dist_ts/classes.controller.d.ts +523 -0
- package/dist_ts/classes.controller.js +10611 -0
- package/dist_ts/classes.controllermanagement.d.ts +32 -0
- package/dist_ts/classes.controllermanagement.js +222 -0
- package/dist_ts/classes.draftmanager.d.ts +30 -0
- package/dist_ts/classes.draftmanager.js +179 -0
- package/dist_ts/classes.embeddeddb.d.ts +30 -0
- package/dist_ts/classes.embeddeddb.js +159 -0
- package/dist_ts/classes.flexframedtransport.d.ts +56 -0
- package/dist_ts/classes.flexframedtransport.js +275 -0
- package/dist_ts/classes.flexmodels.private.d.ts +231 -0
- package/dist_ts/classes.flexmodels.private.js +985 -0
- package/dist_ts/classes.flexmodels.public.d.ts +207 -0
- package/dist_ts/classes.flexmodels.public.js +885 -0
- package/dist_ts/classes.flexprojectionreader.d.ts +89 -0
- package/dist_ts/classes.flexprojectionreader.js +580 -0
- package/dist_ts/classes.flexservice.d.ts +196 -0
- package/dist_ts/classes.flexservice.js +3704 -0
- package/dist_ts/classes.flexstore.d.ts +174 -0
- package/dist_ts/classes.flexstore.js +3400 -0
- package/dist_ts/classes.flexsupervisor.d.ts +105 -0
- package/dist_ts/classes.flexsupervisor.js +1191 -0
- package/dist_ts/classes.gitreversion.d.ts +431 -0
- package/dist_ts/classes.gitreversion.js +10592 -0
- package/dist_ts/classes.harnessoperationmanager.d.ts +113 -0
- package/dist_ts/classes.harnessoperationmanager.js +602 -0
- package/dist_ts/classes.opencodeclient.d.ts +146 -0
- package/dist_ts/classes.opencodeclient.js +3003 -0
- package/dist_ts/classes.opencodesupervisor.d.ts +60 -0
- package/dist_ts/classes.opencodesupervisor.js +1003 -0
- package/dist_ts/classes.passkeymanager.d.ts +34 -0
- package/dist_ts/classes.passkeymanager.js +456 -0
- package/dist_ts/classes.processinspection.d.ts +50 -0
- package/dist_ts/classes.processinspection.js +484 -0
- package/dist_ts/classes.resourcecoordinator.d.ts +64 -0
- package/dist_ts/classes.resourcecoordinator.js +294 -0
- package/dist_ts/classes.sessionintelligencereader.d.ts +13 -0
- package/dist_ts/classes.sessionintelligencereader.js +40 -0
- package/dist_ts/classes.systemmetricssampler.d.ts +53 -0
- package/dist_ts/classes.systemmetricssampler.js +168 -0
- package/dist_ts/classes.terminalmanager.d.ts +95 -0
- package/dist_ts/classes.terminalmanager.js +981 -0
- package/dist_ts/classes.terminalresourcehost.d.ts +20 -0
- package/dist_ts/classes.terminalresourcehost.js +84 -0
- package/dist_ts/classes.upgradecoordinator.d.ts +244 -0
- package/dist_ts/classes.upgradecoordinator.js +2155 -0
- package/dist_ts/classes.upgradetransaction.d.ts +92 -0
- package/dist_ts/classes.upgradetransaction.js +2125 -0
- package/dist_ts/classes.uploadmanager.d.ts +24 -0
- package/dist_ts/classes.uploadmanager.js +210 -0
- package/dist_ts/classes.validation.d.ts +91 -0
- package/dist_ts/classes.validation.js +1087 -0
- package/dist_ts/flexharness.child.d.ts +1 -0
- package/dist_ts/flexharness.child.js +28 -0
- package/dist_ts/functions.canonicaldirectory.d.ts +21 -0
- package/dist_ts/functions.canonicaldirectory.js +144 -0
- package/dist_ts/functions.controllerdataroot.d.ts +15 -0
- package/dist_ts/functions.controllerdataroot.js +76 -0
- package/dist_ts/functions.embeddeddb.d.ts +2 -0
- package/dist_ts/functions.embeddeddb.js +21 -0
- package/dist_ts/functions.flexcredentialstore.d.ts +16 -0
- package/dist_ts/functions.flexcredentialstore.js +93 -0
- package/dist_ts/functions.opencodeauth.d.ts +3 -0
- package/dist_ts/functions.opencodeauth.js +31 -0
- package/dist_ts/functions.runtimeenvironment.d.ts +2 -0
- package/dist_ts/functions.runtimeenvironment.js +79 -0
- package/dist_ts/functions.upgradefollower.d.ts +3 -0
- package/dist_ts/functions.upgradefollower.js +95 -0
- package/dist_ts/index.d.ts +24 -0
- package/dist_ts/index.js +25 -0
- package/dist_ts/interfaces.auth.d.ts +181 -0
- package/dist_ts/interfaces.auth.js +82 -0
- package/dist_ts/interfaces.config.d.ts +34 -0
- package/dist_ts/interfaces.config.js +2 -0
- package/dist_ts/interfaces.flexipc.d.ts +939 -0
- package/dist_ts/interfaces.flexipc.js +1492 -0
- package/dist_ts/interfaces.gitreversion.d.ts +246 -0
- package/dist_ts/interfaces.gitreversion.js +2 -0
- package/dist_ts/interfaces.lifecycle.d.ts +37 -0
- package/dist_ts/interfaces.lifecycle.js +2 -0
- package/dist_ts/interfaces.opencode.d.ts +101 -0
- package/dist_ts/interfaces.opencode.js +3 -0
- package/dist_ts/interfaces.projects.d.ts +156 -0
- package/dist_ts/interfaces.projects.js +5 -0
- package/dist_ts/plugins.d.ts +36 -0
- package/dist_ts/plugins.js +40 -0
- package/dist_ts_interfaces/index.d.ts +2 -0
- package/dist_ts_interfaces/index.js +3 -0
- package/dist_ts_interfaces/interfaces.d.ts +747 -0
- package/dist_ts_interfaces/interfaces.js +47 -0
- package/dist_ts_interfaces/plugins.d.ts +4 -0
- package/dist_ts_interfaces/plugins.js +3 -0
- package/dist_ts_interfaces/requests.d.ts +806 -0
- package/dist_ts_interfaces/requests.js +2 -0
- package/dist_ts_migration/classes.documentmigrationrunner.d.ts +8 -0
- package/dist_ts_migration/classes.documentmigrationrunner.js +24 -0
- package/dist_ts_migration/classes.flexmigrationrunner.d.ts +11 -0
- package/dist_ts_migration/classes.flexmigrationrunner.js +25 -0
- package/dist_ts_migration/classes.flexpostharnessmigrationrunner.d.ts +10 -0
- package/dist_ts_migration/classes.flexpostharnessmigrationrunner.js +15 -0
- package/dist_ts_migration/classes.migrationrunner.d.ts +8 -0
- package/dist_ts_migration/classes.migrationrunner.js +34 -0
- package/dist_ts_migration/index.d.ts +12 -0
- package/dist_ts_migration/index.js +13 -0
- package/dist_ts_migration/v10_flexharnessv3migration.d.ts +11 -0
- package/dist_ts_migration/v10_flexharnessv3migration.js +23 -0
- package/dist_ts_migration/v13_flexprojectionorder.d.ts +11 -0
- package/dist_ts_migration/v13_flexprojectionorder.js +23 -0
- package/dist_ts_migration/v16_flexprovidercredentials.d.ts +22 -0
- package/dist_ts_migration/v16_flexprovidercredentials.js +149 -0
- package/dist_ts_migration/v18_resourcelayout.d.ts +22 -0
- package/dist_ts_migration/v18_resourcelayout.js +23 -0
- package/dist_ts_migration/v18_resourcelayoutmigration.d.ts +6 -0
- package/dist_ts_migration/v18_resourcelayoutmigration.js +61 -0
- package/dist_ts_migration/v19_flexprojectmanagement.d.ts +11 -0
- package/dist_ts_migration/v19_flexprojectmanagement.js +21 -0
- package/dist_ts_migration/v1_embeddeddatabaselocation.d.ts +28 -0
- package/dist_ts_migration/v1_embeddeddatabaselocation.js +415 -0
- package/dist_ts_migration/v22_projectfilesystemidentitymigration.d.ts +7 -0
- package/dist_ts_migration/v22_projectfilesystemidentitymigration.js +105 -0
- package/dist_ts_migration/v2_controllerdataroot.d.ts +130 -0
- package/dist_ts_migration/v2_controllerdataroot.js +1887 -0
- package/dist_ts_migration/v6_protocoldocumentmigration.d.ts +7 -0
- package/dist_ts_migration/v6_protocoldocumentmigration.js +100 -0
- package/dist_ts_migration/v6_protocoldocuments.d.ts +7 -0
- package/dist_ts_migration/v6_protocoldocuments.js +138 -0
- package/html/index.html +13 -0
- package/{LICENSE → license.md} +2 -2
- package/package.json +86 -48
- package/readme.md +480 -0
- package/readme.plan.md +188 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.authmodels.ts +1245 -0
- package/ts/classes.authstore.ts +3274 -0
- package/ts/classes.browserresourcehost.ts +1205 -0
- package/ts/classes.cli.ts +1254 -0
- package/ts/classes.config.ts +351 -0
- package/ts/classes.controller.ts +14426 -0
- package/ts/classes.controllermanagement.ts +330 -0
- package/ts/classes.draftmanager.ts +232 -0
- package/ts/classes.embeddeddb.ts +166 -0
- package/ts/classes.flexframedtransport.ts +283 -0
- package/ts/classes.flexmodels.private.ts +823 -0
- package/ts/classes.flexmodels.public.ts +732 -0
- package/ts/classes.flexprojectionreader.ts +816 -0
- package/ts/classes.flexservice.ts +4302 -0
- package/ts/classes.flexstore.ts +4565 -0
- package/ts/classes.flexsupervisor.ts +1453 -0
- package/ts/classes.gitreversion.ts +13353 -0
- package/ts/classes.harnessoperationmanager.ts +870 -0
- package/ts/classes.opencodeclient.ts +4110 -0
- package/ts/classes.opencodesupervisor.ts +1280 -0
- package/ts/classes.passkeymanager.ts +570 -0
- package/ts/classes.processinspection.ts +623 -0
- package/ts/classes.resourcecoordinator.ts +436 -0
- package/ts/classes.sessionintelligencereader.ts +52 -0
- package/ts/classes.systemmetricssampler.ts +215 -0
- package/ts/classes.terminalmanager.ts +1207 -0
- package/ts/classes.terminalresourcehost.ts +122 -0
- package/ts/classes.upgradecoordinator.ts +2675 -0
- package/ts/classes.upgradetransaction.ts +2900 -0
- package/ts/classes.uploadmanager.ts +240 -0
- package/ts/classes.validation.ts +1409 -0
- package/ts/flexharness.child.ts +35 -0
- package/ts/functions.canonicaldirectory.ts +213 -0
- package/ts/functions.controllerdataroot.ts +107 -0
- package/ts/functions.embeddeddb.ts +22 -0
- package/ts/functions.flexcredentialstore.ts +128 -0
- package/ts/functions.opencodeauth.ts +34 -0
- package/ts/functions.runtimeenvironment.ts +90 -0
- package/ts/functions.upgradefollower.ts +115 -0
- package/ts/index.ts +36 -6
- package/ts/interfaces.auth.ts +316 -0
- package/ts/interfaces.config.ts +37 -0
- package/ts/interfaces.flexipc.ts +2586 -0
- package/ts/interfaces.gitreversion.ts +336 -0
- package/ts/interfaces.lifecycle.ts +46 -0
- package/ts/interfaces.opencode.ts +153 -0
- package/ts/interfaces.projects.ts +182 -0
- package/ts/plugins.ts +64 -0
- package/ts_interfaces/index.ts +2 -0
- package/ts_interfaces/interfaces.ts +827 -0
- package/ts_interfaces/plugins.ts +15 -0
- package/ts_interfaces/requests.ts +1186 -0
- package/ts_migration/classes.documentmigrationrunner.ts +32 -0
- package/ts_migration/classes.flexmigrationrunner.ts +33 -0
- package/ts_migration/classes.flexpostharnessmigrationrunner.ts +22 -0
- package/ts_migration/classes.migrationrunner.ts +40 -0
- package/ts_migration/index.ts +12 -0
- package/ts_migration/v10_flexharnessv3migration.ts +35 -0
- package/ts_migration/v13_flexprojectionorder.ts +33 -0
- package/ts_migration/v16_flexprovidercredentials.ts +196 -0
- package/ts_migration/v18_resourcelayout.ts +55 -0
- package/ts_migration/v18_resourcelayoutmigration.ts +68 -0
- package/ts_migration/v19_flexprojectmanagement.ts +28 -0
- package/ts_migration/v1_embeddeddatabaselocation.ts +560 -0
- package/ts_migration/v22_projectfilesystemidentitymigration.ts +121 -0
- package/ts_migration/v2_controllerdataroot.ts +2349 -0
- package/ts_migration/v6_protocoldocumentmigration.ts +144 -0
- package/ts_migration/v6_protocoldocuments.ts +198 -0
- package/ts_web/00_commitinfo_data.ts +8 -0
- package/ts_web/classes.controllersocketclient.ts +517 -0
- package/ts_web/classes.sessiondraftsync.ts +390 -0
- package/ts_web/elements.harnesscontrollerapp.ts +11494 -0
- package/ts_web/index.ts +2 -0
- package/ts_web/plugins.ts +31 -0
- package/.gitlab-ci.yml +0 -71
- package/.npmignore +0 -5
- package/README.md +0 -40
- package/dist/cli.js +0 -2
- package/dist/index.d.ts +0 -0
- package/dist/index.js +0 -9
- package/dist/mod_bundle/index.d.ts +0 -1
- package/dist/mod_bundle/index.js +0 -18
- package/dist/mod_bundle/mod.plugins.d.ts +0 -4
- package/dist/mod_bundle/mod.plugins.js +0 -11
- package/dist/mod_install/index.d.ts +0 -4
- package/dist/mod_install/index.js +0 -21
- package/dist/mod_install/mod.plugins.d.ts +0 -1
- package/dist/mod_install/mod.plugins.js +0 -7
- package/dist/mod_standard/index.d.ts +0 -4
- package/dist/mod_standard/index.js +0 -21
- package/dist/mod_standard/mod.browser.d.ts +0 -6
- package/dist/mod_standard/mod.browser.js +0 -14
- package/dist/mod_standard/mod.clean.d.ts +0 -4
- package/dist/mod_standard/mod.clean.js +0 -12
- package/dist/mod_standard/mod.compile.d.ts +0 -4
- package/dist/mod_standard/mod.compile.js +0 -21
- package/dist/mod_standard/mod.plugins.d.ts +0 -8
- package/dist/mod_standard/mod.plugins.js +0 -19
- package/dist/mod_standard/mod.test.d.ts +0 -4
- package/dist/mod_standard/mod.test.js +0 -12
- package/dist/plr.cli.d.ts +0 -3
- package/dist/plr.cli.js +0 -57
- package/dist/plr.config.d.ts +0 -11
- package/dist/plr.config.js +0 -26
- package/dist/plr.mods.d.ts +0 -17
- package/dist/plr.mods.js +0 -17
- package/dist/plr.paths.d.ts +0 -19
- package/dist/plr.paths.js +0 -26
- package/dist/plr.plugins.d.ts +0 -8
- package/dist/plr.plugins.js +0 -16
- package/npmextra.json +0 -10
- package/ts/mod_bundle/index.ts +0 -20
- package/ts/mod_bundle/mod.plugins.ts +0 -9
- package/ts/mod_install/index.ts +0 -20
- package/ts/mod_install/mod.plugins.ts +0 -1
- package/ts/mod_standard/index.ts +0 -23
- package/ts/mod_standard/mod.browser.ts +0 -17
- package/ts/mod_standard/mod.clean.ts +0 -13
- package/ts/mod_standard/mod.compile.ts +0 -23
- package/ts/mod_standard/mod.plugins.ts +0 -17
- package/ts/mod_standard/mod.test.ts +0 -13
- package/ts/plr.cli.ts +0 -60
- package/ts/plr.config.ts +0 -36
- package/ts/plr.mods.ts +0 -25
- package/ts/plr.paths.ts +0 -29
- package/ts/plr.plugins.ts +0 -17
- package/tslint.json +0 -3
- package/yarn.lock +0 -3464
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import { hasFlexExactKeys, isFlexPlainObject } from './interfaces.flexipc.js';
|
|
3
|
+
import { assertFlexProviderConnectionDocument, } from './classes.flexmodels.private.js';
|
|
4
|
+
import { FlexPublicCandidateModel, FlexPublicMessageRecordModel, FlexPublicSessionRecordModel, assertFlexPublicCandidateDocument, assertFlexPublicMessageRecordDocument, assertFlexPublicSessionRecordDocument, flexPublicHeadId, flexPublicPageBytesLimit, flexPublicPageLimit, initFlexPublicModels, isFlexPublicCandidateManifest, registerFlexPublicModels, } from './classes.flexmodels.public.js';
|
|
5
|
+
const sha256 = (valueArg) => plugins.crypto.createHash('sha256').update(valueArg).digest('hex');
|
|
6
|
+
const serializedBytes = (valueArg) => Buffer.from(JSON.stringify(valueArg), 'utf8');
|
|
7
|
+
const isNonNegativeInteger = (valueArg) => Number.isSafeInteger(valueArg) && valueArg >= 0;
|
|
8
|
+
const isBoundedString = (valueArg, maximumBytesArg) => typeof valueArg === 'string'
|
|
9
|
+
&& valueArg.length > 0
|
|
10
|
+
&& Buffer.byteLength(valueArg, 'utf8') <= maximumBytesArg;
|
|
11
|
+
const isIsoDate = (valueArg) => typeof valueArg === 'string'
|
|
12
|
+
&& Number.isFinite(Date.parse(valueArg))
|
|
13
|
+
&& new Date(valueArg).toISOString() === valueArg;
|
|
14
|
+
function assertPublicHeadView(valueArg) {
|
|
15
|
+
if (!isFlexPlainObject(valueArg)
|
|
16
|
+
|| !hasFlexExactKeys(valueArg, [
|
|
17
|
+
'id', 'controllerId', 'storageKey', 'revision',
|
|
18
|
+
'currentPublicCandidateId', 'publicCandidates',
|
|
19
|
+
])
|
|
20
|
+
|| !isBoundedString(valueArg.id, 1024)
|
|
21
|
+
|| !isBoundedString(valueArg.controllerId, 512)
|
|
22
|
+
|| !isBoundedString(valueArg.storageKey, 512)
|
|
23
|
+
|| !isNonNegativeInteger(valueArg.revision)
|
|
24
|
+
|| !isBoundedString(valueArg.currentPublicCandidateId, 64)
|
|
25
|
+
|| !Array.isArray(valueArg.publicCandidates)
|
|
26
|
+
|| valueArg.publicCandidates.length < 1
|
|
27
|
+
|| valueArg.publicCandidates.length > 4
|
|
28
|
+
|| !valueArg.publicCandidates.every(isFlexPublicCandidateManifest)
|
|
29
|
+
|| valueArg.publicCandidates[0]?.candidateId !== valueArg.currentPublicCandidateId
|
|
30
|
+
|| valueArg.publicCandidates[0]?.revision !== valueArg.revision)
|
|
31
|
+
throw new FlexProjectionFormatError();
|
|
32
|
+
}
|
|
33
|
+
const projectCandidate = (modelArg) => ({
|
|
34
|
+
id: modelArg.id,
|
|
35
|
+
controllerId: modelArg.controllerId,
|
|
36
|
+
scopeId: modelArg.scopeId,
|
|
37
|
+
candidateId: modelArg.candidateId,
|
|
38
|
+
revision: modelArg.revision,
|
|
39
|
+
sha256: modelArg.sha256,
|
|
40
|
+
bytes: modelArg.bytes,
|
|
41
|
+
sessionRecords: modelArg.sessionRecords,
|
|
42
|
+
messageRecords: modelArg.messageRecords,
|
|
43
|
+
sessionsTruncated: modelArg.sessionsTruncated,
|
|
44
|
+
messagesTruncated: modelArg.messagesTruncated,
|
|
45
|
+
messageBytesTruncated: modelArg.messageBytesTruncated,
|
|
46
|
+
visibleDigest: modelArg.visibleDigest,
|
|
47
|
+
scopeSource: modelArg.scopeSource,
|
|
48
|
+
projectionSources: modelArg.projectionSources,
|
|
49
|
+
createdAt: modelArg.createdAt,
|
|
50
|
+
});
|
|
51
|
+
const projectSessionRecord = (modelArg) => ({
|
|
52
|
+
id: modelArg.id,
|
|
53
|
+
controllerId: modelArg.controllerId,
|
|
54
|
+
scopeId: modelArg.scopeId,
|
|
55
|
+
candidateId: modelArg.candidateId,
|
|
56
|
+
revision: modelArg.revision,
|
|
57
|
+
session: modelArg.session,
|
|
58
|
+
createdAt: modelArg.createdAt,
|
|
59
|
+
});
|
|
60
|
+
const projectMessageRecord = (modelArg) => ({
|
|
61
|
+
id: modelArg.id,
|
|
62
|
+
controllerId: modelArg.controllerId,
|
|
63
|
+
scopeId: modelArg.scopeId,
|
|
64
|
+
candidateId: modelArg.candidateId,
|
|
65
|
+
revision: modelArg.revision,
|
|
66
|
+
messageIndex: modelArg.messageIndex,
|
|
67
|
+
message: modelArg.message,
|
|
68
|
+
createdAt: modelArg.createdAt,
|
|
69
|
+
});
|
|
70
|
+
const compareNewestSession = (leftArg, rightArg) => rightArg.session.updatedAt.localeCompare(leftArg.session.updatedAt)
|
|
71
|
+
|| rightArg.session.createdAt.localeCompare(leftArg.session.createdAt)
|
|
72
|
+
|| leftArg.session.sessionId.localeCompare(rightArg.session.sessionId);
|
|
73
|
+
const compareNewestMessage = (leftArg, rightArg) => rightArg.messageIndex - leftArg.messageIndex;
|
|
74
|
+
const validateLimit = (valueArg) => {
|
|
75
|
+
const selected = valueArg ?? flexPublicPageLimit;
|
|
76
|
+
if (!Number.isSafeInteger(selected) || selected < 1 || selected > flexPublicPageLimit) {
|
|
77
|
+
throw new FlexProjectionCursorError();
|
|
78
|
+
}
|
|
79
|
+
return selected;
|
|
80
|
+
};
|
|
81
|
+
const manifestBytes = (manifestArg) => serializedBytes({
|
|
82
|
+
candidateId: manifestArg.candidateId,
|
|
83
|
+
revision: manifestArg.revision,
|
|
84
|
+
sessionRecords: manifestArg.sessionRecords.map(({ id, sha256: digest, bytes }) => ({
|
|
85
|
+
id, sha256: digest, bytes,
|
|
86
|
+
})),
|
|
87
|
+
messageRecords: manifestArg.messageRecords.map(({ id, sha256: digest, bytes }) => ({
|
|
88
|
+
id, sha256: digest, bytes,
|
|
89
|
+
})),
|
|
90
|
+
sessionsTruncated: manifestArg.sessionsTruncated,
|
|
91
|
+
messagesTruncated: manifestArg.messagesTruncated,
|
|
92
|
+
messageBytesTruncated: manifestArg.messageBytesTruncated,
|
|
93
|
+
visibleDigest: manifestArg.visibleDigest,
|
|
94
|
+
scopeSource: manifestArg.scopeSource,
|
|
95
|
+
projectionSources: manifestArg.projectionSources,
|
|
96
|
+
});
|
|
97
|
+
const verifyRecordManifest = (documentArg, manifestArg) => {
|
|
98
|
+
const bytes = serializedBytes(documentArg);
|
|
99
|
+
if (documentArg.id !== manifestArg.id
|
|
100
|
+
|| bytes.byteLength !== manifestArg.bytes
|
|
101
|
+
|| sha256(bytes) !== manifestArg.sha256)
|
|
102
|
+
throw new FlexProjectionFormatError();
|
|
103
|
+
};
|
|
104
|
+
const recordManifestsEqual = (leftArg, rightArg) => leftArg.length === rightArg.length && leftArg.every((left, index) => {
|
|
105
|
+
const right = rightArg[index];
|
|
106
|
+
return right !== undefined
|
|
107
|
+
&& left.id === right.id
|
|
108
|
+
&& left.sha256 === right.sha256
|
|
109
|
+
&& left.bytes === right.bytes;
|
|
110
|
+
});
|
|
111
|
+
export class FlexProjectionCursorError extends Error {
|
|
112
|
+
code = 'FLEX_PROJECTION_CURSOR_INVALID';
|
|
113
|
+
constructor() {
|
|
114
|
+
super('The Flex projection cursor is invalid.');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export class FlexProjectionStaleCursorError extends Error {
|
|
118
|
+
code = 'FLEX_PROJECTION_CURSOR_STALE';
|
|
119
|
+
constructor() {
|
|
120
|
+
super('The Flex projection cursor refers to an evicted candidate.');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export class FlexProjectionNotFoundError extends Error {
|
|
124
|
+
code = 'FLEX_PROJECTION_NOT_FOUND';
|
|
125
|
+
constructor() {
|
|
126
|
+
super('The requested Flex projection was not found.');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export class FlexProjectionFormatError extends Error {
|
|
130
|
+
code = 'FLEX_PROJECTION_FORMAT_INVALID';
|
|
131
|
+
constructor() {
|
|
132
|
+
super('The Flex public projection is invalid.');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export class FlexProjectionReader {
|
|
136
|
+
database;
|
|
137
|
+
controllerId;
|
|
138
|
+
manager;
|
|
139
|
+
initialized = false;
|
|
140
|
+
databaseOpened = false;
|
|
141
|
+
initPromise;
|
|
142
|
+
closePromise;
|
|
143
|
+
closed = false;
|
|
144
|
+
constructor(optionsArg) {
|
|
145
|
+
this.controllerId = optionsArg.controllerId;
|
|
146
|
+
this.database = new plugins.smartdata.SmartdataDb(optionsArg.database);
|
|
147
|
+
this.manager = { db: this.database };
|
|
148
|
+
registerFlexPublicModels(this.manager);
|
|
149
|
+
}
|
|
150
|
+
async init() {
|
|
151
|
+
if (this.closed)
|
|
152
|
+
throw new Error('The Flex projection reader is closed.');
|
|
153
|
+
if (this.initialized)
|
|
154
|
+
return;
|
|
155
|
+
if (this.initPromise)
|
|
156
|
+
return this.initPromise;
|
|
157
|
+
const initPromise = (async () => {
|
|
158
|
+
try {
|
|
159
|
+
this.databaseOpened = true;
|
|
160
|
+
await this.database.init();
|
|
161
|
+
await initFlexPublicModels();
|
|
162
|
+
if (this.closed)
|
|
163
|
+
throw new Error('The Flex projection reader was closed during startup.');
|
|
164
|
+
this.initialized = true;
|
|
165
|
+
}
|
|
166
|
+
catch (errorArg) {
|
|
167
|
+
if (this.databaseOpened) {
|
|
168
|
+
try {
|
|
169
|
+
await this.database.close();
|
|
170
|
+
this.databaseOpened = false;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
// close() retains retry ownership for a database that did not close.
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
throw errorArg;
|
|
177
|
+
}
|
|
178
|
+
})();
|
|
179
|
+
this.initPromise = initPromise;
|
|
180
|
+
try {
|
|
181
|
+
await initPromise;
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
if (this.initPromise === initPromise)
|
|
185
|
+
this.initPromise = undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async close() {
|
|
189
|
+
if (this.closePromise)
|
|
190
|
+
return this.closePromise;
|
|
191
|
+
this.closed = true;
|
|
192
|
+
const closePromise = (async () => {
|
|
193
|
+
if (this.initPromise)
|
|
194
|
+
await this.initPromise.catch(() => undefined);
|
|
195
|
+
if (this.databaseOpened) {
|
|
196
|
+
await this.database.close();
|
|
197
|
+
this.databaseOpened = false;
|
|
198
|
+
}
|
|
199
|
+
this.initialized = false;
|
|
200
|
+
})();
|
|
201
|
+
this.closePromise = closePromise;
|
|
202
|
+
try {
|
|
203
|
+
await closePromise;
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
if (this.closePromise === closePromise)
|
|
207
|
+
this.closePromise = undefined;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async listSessionPage(scopeIdArg, optionsArg = {}, signalArg) {
|
|
211
|
+
const limit = validateLimit(optionsArg.limit);
|
|
212
|
+
const cursor = optionsArg.cursor
|
|
213
|
+
? this.parseCursor(optionsArg.cursor, 'sessions', scopeIdArg)
|
|
214
|
+
: undefined;
|
|
215
|
+
const selection = await this.selectCandidate(scopeIdArg, cursor, signalArg);
|
|
216
|
+
const records = await this.loadSessionRecords(selection, signalArg);
|
|
217
|
+
const startIndex = cursor
|
|
218
|
+
? this.findAnchorIndex(records, cursor.anchorId, cursor.anchorTimestamp, (record) => record.session.sessionId, (record) => record.session.updatedAt) + 1
|
|
219
|
+
: 0;
|
|
220
|
+
let selected = records.slice(startIndex, startIndex + limit);
|
|
221
|
+
let page = this.createSessionPage(selection, selected, startIndex + selected.length < records.length);
|
|
222
|
+
while (serializedBytes(page).byteLength > flexPublicPageBytesLimit && selected.length > 0) {
|
|
223
|
+
selected = selected.slice(0, -1);
|
|
224
|
+
page = this.createSessionPage(selection, selected, true);
|
|
225
|
+
}
|
|
226
|
+
if (selected.length === 0 && records.length > startIndex)
|
|
227
|
+
throw new FlexProjectionFormatError();
|
|
228
|
+
return page;
|
|
229
|
+
}
|
|
230
|
+
async listAllSessions(scopeIdArg, signalArg) {
|
|
231
|
+
const selection = await this.selectCandidate(scopeIdArg, undefined, signalArg);
|
|
232
|
+
const records = await this.loadSessionRecords(selection, signalArg);
|
|
233
|
+
return {
|
|
234
|
+
candidateId: selection.manifest.candidateId,
|
|
235
|
+
revision: selection.manifest.revision,
|
|
236
|
+
sessions: records.map((record) => JSON.parse(JSON.stringify(record.session))),
|
|
237
|
+
truncated: selection.manifest.sessionsTruncated,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async getSession(scopeIdArg, sessionIdArg, signalArg) {
|
|
241
|
+
const selection = await this.selectCandidate(scopeIdArg, undefined, signalArg);
|
|
242
|
+
const records = await this.loadSessionRecords(selection, signalArg);
|
|
243
|
+
const record = records.find((entry) => entry.session.sessionId === sessionIdArg);
|
|
244
|
+
if (!record)
|
|
245
|
+
throw new FlexProjectionNotFoundError();
|
|
246
|
+
return JSON.parse(JSON.stringify(record.session));
|
|
247
|
+
}
|
|
248
|
+
async listMessagePage(scopeIdArg, sessionIdArg, optionsArg = {}, signalArg) {
|
|
249
|
+
const limit = validateLimit(optionsArg.limit);
|
|
250
|
+
const cursor = optionsArg.cursor
|
|
251
|
+
? this.parseCursor(optionsArg.cursor, 'messages', scopeIdArg, sessionIdArg)
|
|
252
|
+
: undefined;
|
|
253
|
+
const selection = await this.selectCandidate(scopeIdArg, cursor, signalArg);
|
|
254
|
+
const records = (await this.loadMessageRecords(selection, signalArg))
|
|
255
|
+
.filter((entry) => entry.message.sessionId === sessionIdArg)
|
|
256
|
+
.sort(compareNewestMessage);
|
|
257
|
+
const startIndex = cursor
|
|
258
|
+
? records.findIndex((record) => (record.message.messageId === cursor.anchorId
|
|
259
|
+
&& record.messageIndex === cursor.anchorMessageIndex)) + 1
|
|
260
|
+
: 0;
|
|
261
|
+
if (cursor && startIndex === 0)
|
|
262
|
+
throw new FlexProjectionCursorError();
|
|
263
|
+
let newestFirst = records.slice(startIndex, startIndex + limit);
|
|
264
|
+
let page = this.createMessagePage(selection, sessionIdArg, newestFirst, startIndex + newestFirst.length < records.length);
|
|
265
|
+
while (serializedBytes(page).byteLength > flexPublicPageBytesLimit && newestFirst.length > 0) {
|
|
266
|
+
newestFirst = newestFirst.slice(0, -1);
|
|
267
|
+
page = this.createMessagePage(selection, sessionIdArg, newestFirst, true);
|
|
268
|
+
}
|
|
269
|
+
if (newestFirst.length === 0 && records.length > startIndex)
|
|
270
|
+
throw new FlexProjectionFormatError();
|
|
271
|
+
return page;
|
|
272
|
+
}
|
|
273
|
+
async listAllSessionMessages(scopeIdArg, sessionIdArg, signalArg) {
|
|
274
|
+
const selection = await this.selectCandidate(scopeIdArg, undefined, signalArg);
|
|
275
|
+
const records = (await this.loadMessageRecords(selection, signalArg))
|
|
276
|
+
.filter((entry) => entry.message.sessionId === sessionIdArg)
|
|
277
|
+
.sort(compareNewestMessage);
|
|
278
|
+
return {
|
|
279
|
+
candidateId: selection.manifest.candidateId,
|
|
280
|
+
revision: selection.manifest.revision,
|
|
281
|
+
messages: records.map((record) => ({
|
|
282
|
+
messageIndex: record.messageIndex,
|
|
283
|
+
message: JSON.parse(JSON.stringify(record.message)),
|
|
284
|
+
})).reverse(),
|
|
285
|
+
truncated: selection.manifest.messagesTruncated
|
|
286
|
+
|| selection.manifest.messageBytesTruncated,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
async getMessage(scopeIdArg, sessionIdArg, messageIdArg, signalArg) {
|
|
290
|
+
const selection = await this.selectCandidate(scopeIdArg, undefined, signalArg);
|
|
291
|
+
const records = await this.loadMessageRecords(selection, signalArg);
|
|
292
|
+
const record = records.find((entry) => (entry.message.sessionId === sessionIdArg && entry.message.messageId === messageIdArg));
|
|
293
|
+
if (!record)
|
|
294
|
+
throw new FlexProjectionNotFoundError();
|
|
295
|
+
return {
|
|
296
|
+
messageIndex: record.messageIndex,
|
|
297
|
+
message: JSON.parse(JSON.stringify(record.message)),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
async listProviderConnections(signalArg) {
|
|
301
|
+
signalArg?.throwIfAborted();
|
|
302
|
+
await this.init();
|
|
303
|
+
signalArg?.throwIfAborted();
|
|
304
|
+
const cursor = this.database.mongoDb.collection('flex_provider_connections').find({ controllerId: this.controllerId }, {
|
|
305
|
+
projection: {
|
|
306
|
+
_id: 0,
|
|
307
|
+
id: 1,
|
|
308
|
+
controllerId: 1,
|
|
309
|
+
providerId: 1,
|
|
310
|
+
state: 1,
|
|
311
|
+
generation: 1,
|
|
312
|
+
createdAt: 1,
|
|
313
|
+
updatedAt: 1,
|
|
314
|
+
account: 1,
|
|
315
|
+
},
|
|
316
|
+
sort: { updatedAt: -1, id: 1 },
|
|
317
|
+
limit: 513,
|
|
318
|
+
...(signalArg === undefined ? {} : { signal: signalArg }),
|
|
319
|
+
});
|
|
320
|
+
try {
|
|
321
|
+
const rawDocuments = await cursor.toArray();
|
|
322
|
+
if (rawDocuments.length > 512) {
|
|
323
|
+
throw new Error('The persisted Flex provider connection limit was exceeded.');
|
|
324
|
+
}
|
|
325
|
+
return rawDocuments.map((rawDocument) => {
|
|
326
|
+
assertFlexProviderConnectionDocument(rawDocument);
|
|
327
|
+
const document = rawDocument;
|
|
328
|
+
if (document.controllerId !== this.controllerId)
|
|
329
|
+
throw new FlexProjectionFormatError();
|
|
330
|
+
return {
|
|
331
|
+
loginId: document.id,
|
|
332
|
+
providerId: document.providerId,
|
|
333
|
+
status: document.state,
|
|
334
|
+
...(document.account === undefined
|
|
335
|
+
? {}
|
|
336
|
+
: { account: JSON.parse(JSON.stringify(document.account)) }),
|
|
337
|
+
};
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
finally {
|
|
341
|
+
await cursor.close();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
async selectCandidate(scopeIdArg, cursorArg, signalArg) {
|
|
345
|
+
signalArg?.throwIfAborted();
|
|
346
|
+
await this.init();
|
|
347
|
+
signalArg?.throwIfAborted();
|
|
348
|
+
if (cursorArg) {
|
|
349
|
+
const head = await this.loadHead(scopeIdArg, signalArg);
|
|
350
|
+
const manifest = head.publicCandidates.find((candidate) => (candidate.candidateId === cursorArg.candidateId
|
|
351
|
+
&& candidate.revision === cursorArg.revision));
|
|
352
|
+
if (!manifest)
|
|
353
|
+
throw new FlexProjectionStaleCursorError();
|
|
354
|
+
const candidate = await this.loadCandidate(scopeIdArg, manifest, signalArg);
|
|
355
|
+
if (!candidate)
|
|
356
|
+
throw new FlexProjectionStaleCursorError();
|
|
357
|
+
return { head, manifest, candidate };
|
|
358
|
+
}
|
|
359
|
+
let head = await this.loadHead(scopeIdArg, signalArg);
|
|
360
|
+
let manifest = head.publicCandidates.find((candidate) => candidate.candidateId === head.currentPublicCandidateId);
|
|
361
|
+
if (!manifest)
|
|
362
|
+
throw new FlexProjectionFormatError();
|
|
363
|
+
let candidate = await this.loadCandidate(scopeIdArg, manifest, signalArg);
|
|
364
|
+
if (!candidate) {
|
|
365
|
+
head = await this.loadHead(scopeIdArg, signalArg);
|
|
366
|
+
manifest = head.publicCandidates.find((entry) => entry.candidateId === head.currentPublicCandidateId);
|
|
367
|
+
if (!manifest)
|
|
368
|
+
throw new FlexProjectionFormatError();
|
|
369
|
+
candidate = await this.loadCandidate(scopeIdArg, manifest, signalArg);
|
|
370
|
+
}
|
|
371
|
+
if (!candidate)
|
|
372
|
+
throw new FlexProjectionFormatError();
|
|
373
|
+
return { head, manifest, candidate };
|
|
374
|
+
}
|
|
375
|
+
async loadHead(scopeIdArg, signalArg) {
|
|
376
|
+
const raw = await this.database.mongoDb.collection('flex_public_heads').findOne({ id: flexPublicHeadId(this.controllerId, scopeIdArg) }, {
|
|
377
|
+
projection: {
|
|
378
|
+
_id: 0,
|
|
379
|
+
id: 1,
|
|
380
|
+
controllerId: 1,
|
|
381
|
+
storageKey: 1,
|
|
382
|
+
revision: 1,
|
|
383
|
+
currentPublicCandidateId: 1,
|
|
384
|
+
publicCandidates: 1,
|
|
385
|
+
},
|
|
386
|
+
...(signalArg === undefined ? {} : { signal: signalArg }),
|
|
387
|
+
});
|
|
388
|
+
if (!raw)
|
|
389
|
+
throw new FlexProjectionNotFoundError();
|
|
390
|
+
assertPublicHeadView(raw);
|
|
391
|
+
if (raw.controllerId !== this.controllerId || raw.storageKey !== scopeIdArg) {
|
|
392
|
+
throw new FlexProjectionFormatError();
|
|
393
|
+
}
|
|
394
|
+
return raw;
|
|
395
|
+
}
|
|
396
|
+
async loadCandidate(scopeIdArg, manifestArg, signalArg) {
|
|
397
|
+
const raw = await FlexPublicCandidateModel.collection.mongoDbCollection.findOne({
|
|
398
|
+
candidateId: manifestArg.candidateId,
|
|
399
|
+
controllerId: this.controllerId,
|
|
400
|
+
scopeId: scopeIdArg,
|
|
401
|
+
}, {
|
|
402
|
+
projection: { _id: 0 },
|
|
403
|
+
...(signalArg === undefined ? {} : { signal: signalArg }),
|
|
404
|
+
});
|
|
405
|
+
if (!raw)
|
|
406
|
+
return undefined;
|
|
407
|
+
const candidate = projectCandidate(raw);
|
|
408
|
+
assertFlexPublicCandidateDocument(candidate);
|
|
409
|
+
const bytes = manifestBytes(manifestArg);
|
|
410
|
+
if (candidate.candidateId !== manifestArg.candidateId
|
|
411
|
+
|| candidate.revision !== manifestArg.revision
|
|
412
|
+
|| candidate.sha256 !== manifestArg.sha256
|
|
413
|
+
|| candidate.bytes !== manifestArg.bytes
|
|
414
|
+
|| !recordManifestsEqual(candidate.sessionRecords, manifestArg.sessionRecords)
|
|
415
|
+
|| !recordManifestsEqual(candidate.messageRecords, manifestArg.messageRecords)
|
|
416
|
+
|| candidate.sessionsTruncated !== manifestArg.sessionsTruncated
|
|
417
|
+
|| candidate.messagesTruncated !== manifestArg.messagesTruncated
|
|
418
|
+
|| candidate.messageBytesTruncated !== manifestArg.messageBytesTruncated
|
|
419
|
+
|| bytes.byteLength !== manifestArg.bytes
|
|
420
|
+
|| sha256(bytes) !== manifestArg.sha256)
|
|
421
|
+
throw new FlexProjectionFormatError();
|
|
422
|
+
return candidate;
|
|
423
|
+
}
|
|
424
|
+
async loadSessionRecords(selectionArg, signalArg) {
|
|
425
|
+
const cursor = FlexPublicSessionRecordModel.collection.mongoDbCollection.find({
|
|
426
|
+
candidateId: selectionArg.candidate.candidateId,
|
|
427
|
+
controllerId: this.controllerId,
|
|
428
|
+
scopeId: selectionArg.head.storageKey,
|
|
429
|
+
}, {
|
|
430
|
+
projection: { _id: 0 },
|
|
431
|
+
...(signalArg === undefined ? {} : { signal: signalArg }),
|
|
432
|
+
});
|
|
433
|
+
try {
|
|
434
|
+
const documents = await cursor.toArray();
|
|
435
|
+
if (documents.length !== selectionArg.manifest.sessionRecords.length) {
|
|
436
|
+
throw new FlexProjectionFormatError();
|
|
437
|
+
}
|
|
438
|
+
const manifestById = new Map(selectionArg.manifest.sessionRecords.map((manifest) => [manifest.id, manifest]));
|
|
439
|
+
return documents.map((raw) => {
|
|
440
|
+
const document = projectSessionRecord(raw);
|
|
441
|
+
assertFlexPublicSessionRecordDocument(document);
|
|
442
|
+
const manifest = manifestById.get(document.id);
|
|
443
|
+
if (!manifest || document.revision !== selectionArg.manifest.revision) {
|
|
444
|
+
throw new FlexProjectionFormatError();
|
|
445
|
+
}
|
|
446
|
+
verifyRecordManifest(document, manifest);
|
|
447
|
+
return document;
|
|
448
|
+
}).sort(compareNewestSession);
|
|
449
|
+
}
|
|
450
|
+
finally {
|
|
451
|
+
await cursor.close();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
async loadMessageRecords(selectionArg, signalArg) {
|
|
455
|
+
const cursor = FlexPublicMessageRecordModel.collection.mongoDbCollection.find({
|
|
456
|
+
candidateId: selectionArg.candidate.candidateId,
|
|
457
|
+
controllerId: this.controllerId,
|
|
458
|
+
scopeId: selectionArg.head.storageKey,
|
|
459
|
+
}, {
|
|
460
|
+
projection: { _id: 0 },
|
|
461
|
+
...(signalArg === undefined ? {} : { signal: signalArg }),
|
|
462
|
+
});
|
|
463
|
+
try {
|
|
464
|
+
const documents = await cursor.toArray();
|
|
465
|
+
if (documents.length !== selectionArg.manifest.messageRecords.length) {
|
|
466
|
+
throw new FlexProjectionFormatError();
|
|
467
|
+
}
|
|
468
|
+
const manifestById = new Map(selectionArg.manifest.messageRecords.map((manifest) => [manifest.id, manifest]));
|
|
469
|
+
const records = documents.map((raw) => {
|
|
470
|
+
const document = projectMessageRecord(raw);
|
|
471
|
+
assertFlexPublicMessageRecordDocument(document);
|
|
472
|
+
const manifest = manifestById.get(document.id);
|
|
473
|
+
if (!manifest || document.revision !== selectionArg.manifest.revision) {
|
|
474
|
+
throw new FlexProjectionFormatError();
|
|
475
|
+
}
|
|
476
|
+
verifyRecordManifest(document, manifest);
|
|
477
|
+
return document;
|
|
478
|
+
});
|
|
479
|
+
if (new Set(records.map((record) => (`${record.message.sessionId}\0${record.messageIndex}`))).size !== records.length)
|
|
480
|
+
throw new FlexProjectionFormatError();
|
|
481
|
+
return records;
|
|
482
|
+
}
|
|
483
|
+
finally {
|
|
484
|
+
await cursor.close();
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
createSessionPage(selectionArg, recordsArg, hasMoreArg) {
|
|
488
|
+
const anchor = recordsArg.at(-1);
|
|
489
|
+
return {
|
|
490
|
+
candidateId: selectionArg.manifest.candidateId,
|
|
491
|
+
revision: selectionArg.manifest.revision,
|
|
492
|
+
sessions: recordsArg.map((record) => JSON.parse(JSON.stringify(record.session))),
|
|
493
|
+
...(hasMoreArg && anchor ? {
|
|
494
|
+
nextCursor: this.encodeCursor({
|
|
495
|
+
version: 2,
|
|
496
|
+
kind: 'sessions',
|
|
497
|
+
controllerId: this.controllerId,
|
|
498
|
+
scopeId: selectionArg.head.storageKey,
|
|
499
|
+
candidateId: selectionArg.manifest.candidateId,
|
|
500
|
+
revision: selectionArg.manifest.revision,
|
|
501
|
+
anchorId: anchor.session.sessionId,
|
|
502
|
+
anchorTimestamp: anchor.session.updatedAt,
|
|
503
|
+
}),
|
|
504
|
+
} : {}),
|
|
505
|
+
truncated: selectionArg.manifest.sessionsTruncated,
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
createMessagePage(selectionArg, sessionIdArg, newestFirstArg, hasMoreArg) {
|
|
509
|
+
const anchor = newestFirstArg.at(-1);
|
|
510
|
+
return {
|
|
511
|
+
candidateId: selectionArg.manifest.candidateId,
|
|
512
|
+
revision: selectionArg.manifest.revision,
|
|
513
|
+
messages: newestFirstArg
|
|
514
|
+
.map((record) => ({
|
|
515
|
+
messageIndex: record.messageIndex,
|
|
516
|
+
message: JSON.parse(JSON.stringify(record.message)),
|
|
517
|
+
}))
|
|
518
|
+
.reverse(),
|
|
519
|
+
...(hasMoreArg && anchor ? {
|
|
520
|
+
nextCursor: this.encodeCursor({
|
|
521
|
+
version: 2,
|
|
522
|
+
kind: 'messages',
|
|
523
|
+
controllerId: this.controllerId,
|
|
524
|
+
scopeId: selectionArg.head.storageKey,
|
|
525
|
+
candidateId: selectionArg.manifest.candidateId,
|
|
526
|
+
revision: selectionArg.manifest.revision,
|
|
527
|
+
anchorId: anchor.message.messageId,
|
|
528
|
+
anchorMessageIndex: anchor.messageIndex,
|
|
529
|
+
sessionId: sessionIdArg,
|
|
530
|
+
}),
|
|
531
|
+
} : {}),
|
|
532
|
+
truncated: selectionArg.manifest.messagesTruncated
|
|
533
|
+
|| selectionArg.manifest.messageBytesTruncated,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
encodeCursor(cursorArg) {
|
|
537
|
+
return serializedBytes(cursorArg).toString('base64url');
|
|
538
|
+
}
|
|
539
|
+
parseCursor(cursorArg, kindArg, scopeIdArg, sessionIdArg) {
|
|
540
|
+
if (!isBoundedString(cursorArg, 4096))
|
|
541
|
+
throw new FlexProjectionCursorError();
|
|
542
|
+
let parsed;
|
|
543
|
+
try {
|
|
544
|
+
const bytes = Buffer.from(cursorArg, 'base64url');
|
|
545
|
+
if (bytes.toString('base64url') !== cursorArg)
|
|
546
|
+
throw new Error('non-canonical');
|
|
547
|
+
parsed = JSON.parse(bytes.toString('utf8'));
|
|
548
|
+
}
|
|
549
|
+
catch {
|
|
550
|
+
throw new FlexProjectionCursorError();
|
|
551
|
+
}
|
|
552
|
+
if (!isFlexPlainObject(parsed)
|
|
553
|
+
|| !hasFlexExactKeys(parsed, [
|
|
554
|
+
'version', 'kind', 'controllerId', 'scopeId', 'candidateId',
|
|
555
|
+
'revision', 'anchorId',
|
|
556
|
+
], ['sessionId', 'anchorTimestamp', 'anchorMessageIndex'])
|
|
557
|
+
|| parsed.version !== 2
|
|
558
|
+
|| parsed.kind !== kindArg
|
|
559
|
+
|| parsed.controllerId !== this.controllerId
|
|
560
|
+
|| parsed.scopeId !== scopeIdArg
|
|
561
|
+
|| !isBoundedString(parsed.candidateId, 64)
|
|
562
|
+
|| !isNonNegativeInteger(parsed.revision)
|
|
563
|
+
|| !isBoundedString(parsed.anchorId, 512)
|
|
564
|
+
|| (kindArg === 'messages' && (parsed.sessionId !== sessionIdArg
|
|
565
|
+
|| !isNonNegativeInteger(parsed.anchorMessageIndex)
|
|
566
|
+
|| parsed.anchorTimestamp !== undefined))
|
|
567
|
+
|| (kindArg === 'sessions' && (parsed.sessionId !== undefined
|
|
568
|
+
|| !isIsoDate(parsed.anchorTimestamp)
|
|
569
|
+
|| parsed.anchorMessageIndex !== undefined)))
|
|
570
|
+
throw new FlexProjectionCursorError();
|
|
571
|
+
return parsed;
|
|
572
|
+
}
|
|
573
|
+
findAnchorIndex(recordsArg, anchorIdArg, anchorTimestampArg, idArg, timestampArg) {
|
|
574
|
+
const index = recordsArg.findIndex((record) => (idArg(record) === anchorIdArg && timestampArg(record) === anchorTimestampArg));
|
|
575
|
+
if (index < 0)
|
|
576
|
+
throw new FlexProjectionCursorError();
|
|
577
|
+
return index;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5mbGV4cHJvamVjdGlvbnJlYWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NsYXNzZXMuZmxleHByb2plY3Rpb25yZWFkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFLeEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDOUUsT0FBTyxFQUNMLG9DQUFvQyxHQUVyQyxNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIsNEJBQTRCLEVBQzVCLDRCQUE0QixFQU01QixpQ0FBaUMsRUFDakMscUNBQXFDLEVBQ3JDLHFDQUFxQyxFQUNyQyxnQkFBZ0IsRUFDaEIsd0JBQXdCLEVBQ3hCLG1CQUFtQixFQUNuQixvQkFBb0IsRUFDcEIsNkJBQTZCLEVBQzdCLHdCQUF3QixHQUN6QixNQUFNLGdDQUFnQyxDQUFDO0FBOEV4QyxNQUFNLE1BQU0sR0FBRyxDQUFDLFFBQTZCLEVBQVUsRUFBRSxDQUN2RCxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBRXJFLE1BQU0sZUFBZSxHQUFHLENBQUMsUUFBaUIsRUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBRXJHLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxRQUFpQixFQUFzQixFQUFFLENBQ3JFLE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUssUUFBbUIsSUFBSSxDQUFDLENBQUM7QUFFOUQsTUFBTSxlQUFlLEdBQUcsQ0FBQyxRQUFpQixFQUFFLGVBQXVCLEVBQXNCLEVBQUUsQ0FD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
|