keri-ts 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/esm/keri/npm/src/acdc/authoring.js +195 -0
- package/esm/keri/npm/src/acdc/chaining.js +223 -89
- package/esm/keri/npm/src/acdc/custody.js +164 -0
- package/esm/keri/npm/src/acdc/dhking.js +244 -32
- package/esm/keri/npm/src/acdc/observing.js +2 -2
- package/esm/keri/npm/src/acdc/regbasing.js +30 -29
- package/esm/keri/npm/src/acdc/regengine.js +4 -6
- package/esm/keri/npm/src/acdc/registering.js +13 -10
- package/esm/keri/npm/src/acdc/registraring.js +4 -9
- package/esm/keri/npm/src/acdc/salting.js +143 -26
- package/esm/keri/npm/src/acdc/scheming.js +93 -54
- package/esm/keri/npm/src/acdc/unblinding.js +120 -99
- package/esm/keri/npm/src/app/bootstrap/authenticating.js +4 -6
- package/esm/keri/npm/src/app/bootstrap/oobi-resolving.js +41 -0
- package/esm/keri/npm/src/app/bootstrap/oobiery.js +5 -7
- package/esm/keri/npm/src/app/credentials/credential-revoking.js +1 -0
- package/esm/keri/npm/src/app/credentials/credential-workflows.js +2 -0
- package/esm/keri/npm/src/app/credentials/registry-settling.js +44 -0
- package/esm/keri/npm/src/app/credentials/root-replicating.js +131 -0
- package/esm/keri/npm/src/app/credentials/root-replicator.js +198 -0
- package/esm/keri/npm/src/app/credentials/tel-completion.js +36 -0
- package/esm/keri/npm/src/app/credentials/verifying.js +12 -3
- package/esm/keri/npm/src/app/delivery/forwarding.js +64 -9
- package/esm/keri/npm/src/app/exchanges/exchanging.js +24 -15
- package/esm/keri/npm/src/app/identity/challenging.js +50 -0
- package/esm/keri/npm/src/app/identity/configing.js +17 -43
- package/esm/keri/npm/src/app/identity/delegating.js +77 -77
- package/esm/keri/npm/src/app/identity/delegation-approval.js +333 -0
- package/esm/keri/npm/src/app/identity/event-completion.js +154 -0
- package/esm/keri/npm/src/app/identity/habbing.js +183 -41
- package/esm/keri/npm/src/app/identity/keeping.js +78 -5
- package/esm/keri/npm/src/app/identity/lmdb-habery.js +12 -0
- package/esm/keri/npm/src/app/ipex/group-ipex.js +327 -0
- package/esm/keri/npm/src/app/ipex/group-issuance.js +902 -0
- package/esm/keri/npm/src/app/ipex/ipex-admitting.js +120 -0
- package/esm/keri/npm/src/app/ipex/ipex-conversation.js +197 -0
- package/esm/keri/npm/src/app/ipex/ipex-discloser.js +591 -0
- package/esm/keri/npm/src/app/ipex/ipex-granting.js +93 -0
- package/esm/keri/npm/src/app/ipex/ipex-graph.js +7 -70
- package/esm/keri/npm/src/app/ipex/ipex-grouping.js +42 -16
- package/esm/keri/npm/src/app/ipex/ipex-v2.js +21 -5
- package/esm/keri/npm/src/app/ipex/ipexing.js +1 -1
- package/esm/keri/npm/src/app/ipex/issuance.js +888 -0
- package/esm/keri/npm/src/app/ipex/pending-presentations.js +46 -0
- package/esm/keri/npm/src/app/ipex/presentation-files.js +200 -0
- package/esm/keri/npm/src/app/ipex/presenting.js +401 -0
- package/esm/keri/npm/src/app/ipex/receive-issuance.js +86 -0
- package/esm/keri/npm/src/app/ipex/unblinding-workflow.js +660 -0
- package/esm/keri/npm/src/app/mailbox/ipex-arrival.js +103 -0
- package/esm/keri/npm/src/app/mailbox/kel-publisher.js +322 -0
- package/esm/keri/npm/src/app/mailbox/kel-publishing.js +65 -0
- package/esm/keri/npm/src/app/mailbox/kel-submission.js +24 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-admin.js +208 -0
- package/esm/keri/npm/src/app/mailbox/mailbox-poller.js +212 -47
- package/esm/keri/npm/src/app/mailbox/mailboxing.js +15 -14
- package/esm/keri/npm/src/app/multisig/counseling.js +482 -0
- package/esm/keri/npm/src/app/multisig/group-members.js +32 -0
- package/esm/keri/npm/src/app/multisig/grouping.js +4 -3
- package/esm/keri/npm/src/app/multisig/multisig-workflows.js +101 -141
- package/esm/keri/npm/src/app/multisig/proposals.js +281 -0
- package/esm/keri/npm/src/app/multisig/proposing.js +122 -0
- package/esm/keri/npm/src/app/notifications/notifying.js +5 -9
- package/esm/keri/npm/src/app/notifications/signaling.js +5 -5
- package/esm/keri/npm/src/app/protocol/parsering.js +26 -1
- package/esm/keri/npm/src/app/protocol/protocol-processing.js +44 -6
- package/esm/keri/npm/src/app/queries/query-workflows.js +98 -0
- package/esm/keri/npm/src/app/queries/witness-inquisitor.js +2 -2
- package/esm/keri/npm/src/app/runtime/agent-runtime.js +113 -65
- package/esm/keri/npm/src/app/runtime/cue-runtime.js +3 -6
- package/esm/keri/npm/src/app/runtime/delivery-outbox.js +87 -0
- package/esm/keri/npm/src/app/runtime/doing.js +17 -0
- package/esm/keri/npm/src/app/runtime/ipex-auxiliaries.js +207 -0
- package/esm/keri/npm/src/app/runtime/operation-owners.js +151 -0
- package/esm/keri/npm/src/app/runtime/retry-backoff.js +93 -0
- package/esm/keri/npm/src/app/runtime/workflow-contract.js +80 -0
- package/esm/keri/npm/src/app/transport/byte-source.js +6 -42
- package/esm/keri/npm/src/app/transport/cesr-egress.js +77 -13
- package/esm/keri/npm/src/app/transport/file-bytes.js +41 -0
- package/esm/keri/npm/src/app/transport/http-client.js +25 -6
- package/esm/keri/npm/src/app/transport/http-messenger.js +14 -9
- package/esm/keri/npm/src/app/transport/message-source.js +1 -1
- package/esm/keri/npm/src/app/transport/messengering.js +3 -4
- package/esm/keri/npm/src/app/transport/node-http-client.js +21 -0
- package/esm/keri/npm/src/app/transport/tcp-dialer.js +14 -0
- package/esm/keri/npm/src/app/witness/http-endpoints.js +4 -4
- package/esm/keri/npm/src/app/witness/receipt-client.js +2 -2
- package/esm/keri/npm/src/cli/common/context.js +2 -2
- package/esm/keri/npm/src/cli/common/event-completion.js +49 -0
- package/esm/keri/npm/src/cli/common/existing.js +3 -5
- package/esm/keri/npm/src/cli/common/runtime-workers.js +23 -0
- package/esm/keri/npm/src/cli/credentials/ipex.js +159 -191
- package/esm/keri/npm/src/cli/credentials/vc.js +53 -72
- package/esm/keri/npm/src/cli/endpoints/did.js +12 -3
- package/esm/keri/npm/src/cli/endpoints/oobi-clean.js +4 -3
- package/esm/keri/npm/src/cli/endpoints/oobi.js +12 -15
- package/esm/keri/npm/src/cli/identity/challenge.js +9 -35
- package/esm/keri/npm/src/cli/identity/delegate.js +81 -258
- package/esm/keri/npm/src/cli/identity/incept.js +17 -34
- package/esm/keri/npm/src/cli/identity/init.js +4 -3
- package/esm/keri/npm/src/cli/identity/interact.js +7 -19
- package/esm/keri/npm/src/cli/identity/rotate.js +10 -38
- package/esm/keri/npm/src/cli/index.js +3 -1
- package/esm/keri/npm/src/cli/messaging/exchange.js +2 -2
- package/esm/keri/npm/src/cli/messaging/group-join.js +79 -0
- package/esm/keri/npm/src/cli/messaging/group-wait.js +88 -0
- package/esm/keri/npm/src/cli/messaging/multisig.js +187 -250
- package/esm/keri/npm/src/cli/messaging/root-copy-lines.js +31 -0
- package/esm/keri/npm/src/cli/tools/annotate.js +2 -1
- package/esm/keri/npm/src/cli/tools/benchmark.js +2 -1
- package/esm/keri/npm/src/cli/tools/db-dump.js +1 -4
- package/esm/keri/npm/src/core/bytes.js +9 -0
- package/esm/keri/npm/src/core/kel/delegation-ancestry.js +92 -0
- package/esm/keri/npm/src/core/kel/eventing.js +67 -12
- package/esm/keri/npm/src/core/kel/kever.js +11 -9
- package/esm/keri/npm/src/core/mailbox/kram-policy.js +41 -9
- package/esm/keri/npm/src/core/mailbox/kram-pruning.js +15 -22
- package/esm/keri/npm/src/core/mailbox/kram-staging.js +2 -2
- package/esm/keri/npm/src/core/mailbox/kraming.js +2 -0
- package/esm/keri/npm/src/core/records.js +23 -0
- package/esm/keri/npm/src/core/routing.js +15 -2
- package/esm/keri/npm/src/db/basing.js +183 -205
- package/esm/keri/npm/src/db/core/dber.js +1062 -0
- package/esm/keri/npm/src/db/core/index.js +4 -2
- package/esm/keri/npm/src/db/core/indexeddb-persistence.js +221 -0
- package/esm/keri/npm/src/db/core/lmdb-opener.js +30 -0
- package/esm/keri/npm/src/db/core/lmdber.js +199 -1067
- package/esm/keri/npm/src/db/core/memstore.js +532 -0
- package/esm/keri/npm/src/db/core/path-manager.js +109 -223
- package/esm/keri/npm/src/db/core/store-owner.js +104 -0
- package/esm/keri/npm/src/db/core/webdber.js +252 -0
- package/esm/keri/npm/src/db/escrowing.js +2 -2
- package/esm/keri/npm/src/db/exchange/exchange-nests.js +3 -2
- package/esm/keri/npm/src/db/indexeddb.js +98 -0
- package/esm/keri/npm/src/db/keeping.js +38 -123
- package/esm/keri/npm/src/db/koming.js +1 -1
- package/esm/keri/npm/src/db/lmdb-stores.js +68 -0
- package/esm/keri/npm/src/db/lmdb.js +6 -0
- package/esm/keri/npm/src/db/mailbox/mailboxing.js +12 -65
- package/esm/keri/npm/src/db/noting.js +11 -55
- package/esm/keri/npm/src/db/reger.js +43 -105
- package/esm/keri/npm/src/db/replay/witness-replay.js +2 -20
- package/esm/keri/npm/src/db/store-lock.js +150 -0
- package/esm/keri/npm/src/db/subing.js +1 -1
- package/esm/keri/npm/src/npm/db-indexeddb.browser.js +2 -0
- package/esm/keri/npm/src/npm/db-indexeddb.js +3 -0
- package/esm/keri/npm/src/npm/db-lmdb.js +3 -0
- package/esm/keri/npm/src/npm/db.browser.js +2 -0
- package/esm/keri/npm/src/npm/index.browser.js +9 -0
- package/esm/keri/npm/src/npm/runtime-node.js +3 -0
- package/esm/keri/npm/src/npm/runtime-web.browser.js +2 -0
- package/esm/keri/npm/src/npm/runtime-web.js +3 -0
- package/esm/keri/npm/src/npm/runtime.browser.js +2 -0
- package/esm/keri/npm/src/runtime/index.js +58 -12
- package/esm/keri/npm/src/runtime/node.js +14 -0
- package/esm/keri/npm/src/runtime/web/output-barrier.js +47 -0
- package/esm/keri/npm/src/runtime/web/persistent-storage.js +37 -0
- package/esm/keri/npm/src/runtime/web.js +10 -0
- package/esm/keri/npm/src/vdr/eventing.js +1 -1
- package/esm/keri/npm/src/vdr/tel-publication.js +19 -3
- package/esm/keri/npm/src/version.js +2 -2
- package/package.json +24 -4
- package/types/acdc/authoring.d.ts +54 -0
- package/types/acdc/authoring.d.ts.map +1 -0
- package/types/acdc/chaining.d.ts +56 -6
- package/types/acdc/chaining.d.ts.map +1 -1
- package/types/acdc/custody.d.ts +77 -0
- package/types/acdc/custody.d.ts.map +1 -0
- package/types/acdc/dhking.d.ts +94 -3
- package/types/acdc/dhking.d.ts.map +1 -1
- package/types/acdc/regbasing.d.ts +11 -6
- package/types/acdc/regbasing.d.ts.map +1 -1
- package/types/acdc/regengine.d.ts.map +1 -1
- package/types/acdc/registering.d.ts +8 -4
- package/types/acdc/registering.d.ts.map +1 -1
- package/types/acdc/registraring.d.ts.map +1 -1
- package/types/acdc/salting.d.ts +59 -7
- package/types/acdc/salting.d.ts.map +1 -1
- package/types/acdc/scheming.d.ts +2 -0
- package/types/acdc/scheming.d.ts.map +1 -1
- package/types/acdc/unblinding.d.ts +58 -19
- package/types/acdc/unblinding.d.ts.map +1 -1
- package/types/app/bootstrap/authenticating.d.ts +3 -1
- package/types/app/bootstrap/authenticating.d.ts.map +1 -1
- package/types/app/bootstrap/oobi-resolving.d.ts +92 -0
- package/types/app/bootstrap/oobi-resolving.d.ts.map +1 -0
- package/types/app/bootstrap/oobiery.d.ts +3 -1
- package/types/app/bootstrap/oobiery.d.ts.map +1 -1
- package/types/app/credentials/credential-revoking.d.ts +3 -0
- package/types/app/credentials/credential-revoking.d.ts.map +1 -1
- package/types/app/credentials/credential-workflows.d.ts +5 -0
- package/types/app/credentials/credential-workflows.d.ts.map +1 -1
- package/types/app/credentials/registry-settling.d.ts +85 -0
- package/types/app/credentials/registry-settling.d.ts.map +1 -0
- package/types/app/credentials/root-replicating.d.ts +97 -0
- package/types/app/credentials/root-replicating.d.ts.map +1 -0
- package/types/app/credentials/root-replicator.d.ts +105 -0
- package/types/app/credentials/root-replicator.d.ts.map +1 -0
- package/types/app/credentials/tel-completion.d.ts +55 -0
- package/types/app/credentials/tel-completion.d.ts.map +1 -0
- package/types/app/credentials/verifying.d.ts +2 -1
- package/types/app/credentials/verifying.d.ts.map +1 -1
- package/types/app/delivery/forwarding.d.ts +16 -0
- package/types/app/delivery/forwarding.d.ts.map +1 -1
- package/types/app/exchanges/exchanging.d.ts +2 -0
- package/types/app/exchanges/exchanging.d.ts.map +1 -1
- package/types/app/identity/challenging.d.ts +54 -0
- package/types/app/identity/challenging.d.ts.map +1 -1
- package/types/app/identity/configing.d.ts +7 -5
- package/types/app/identity/configing.d.ts.map +1 -1
- package/types/app/identity/delegating.d.ts +21 -4
- package/types/app/identity/delegating.d.ts.map +1 -1
- package/types/app/identity/delegation-approval.d.ts +228 -0
- package/types/app/identity/delegation-approval.d.ts.map +1 -0
- package/types/app/identity/event-completion.d.ts +151 -0
- package/types/app/identity/event-completion.d.ts.map +1 -0
- package/types/app/identity/habbing.d.ts +90 -7
- package/types/app/identity/habbing.d.ts.map +1 -1
- package/types/app/identity/keeping.d.ts +50 -4
- package/types/app/identity/keeping.d.ts.map +1 -1
- package/types/app/identity/lmdb-habery.d.ts +6 -0
- package/types/app/identity/lmdb-habery.d.ts.map +1 -0
- package/types/app/ipex/group-ipex.d.ts +247 -0
- package/types/app/ipex/group-ipex.d.ts.map +1 -0
- package/types/app/ipex/group-issuance.d.ts +281 -0
- package/types/app/ipex/group-issuance.d.ts.map +1 -0
- package/types/app/ipex/ipex-admitting.d.ts +47 -0
- package/types/app/ipex/ipex-admitting.d.ts.map +1 -0
- package/types/app/ipex/ipex-conversation.d.ts +195 -0
- package/types/app/ipex/ipex-conversation.d.ts.map +1 -0
- package/types/app/ipex/ipex-discloser.d.ts +156 -0
- package/types/app/ipex/ipex-discloser.d.ts.map +1 -0
- package/types/app/ipex/ipex-granting.d.ts +145 -0
- package/types/app/ipex/ipex-granting.d.ts.map +1 -0
- package/types/app/ipex/ipex-graph.d.ts +4 -4
- package/types/app/ipex/ipex-graph.d.ts.map +1 -1
- package/types/app/ipex/ipex-grouping.d.ts +18 -0
- package/types/app/ipex/ipex-grouping.d.ts.map +1 -1
- package/types/app/ipex/ipex-v2.d.ts +11 -2
- package/types/app/ipex/ipex-v2.d.ts.map +1 -1
- package/types/app/ipex/ipexing.d.ts +3 -0
- package/types/app/ipex/ipexing.d.ts.map +1 -1
- package/types/app/ipex/issuance.d.ts +443 -0
- package/types/app/ipex/issuance.d.ts.map +1 -0
- package/types/app/ipex/pending-presentations.d.ts +25 -0
- package/types/app/ipex/pending-presentations.d.ts.map +1 -0
- package/types/app/ipex/presentation-files.d.ts +47 -0
- package/types/app/ipex/presentation-files.d.ts.map +1 -0
- package/types/app/ipex/presenting.d.ts +298 -0
- package/types/app/ipex/presenting.d.ts.map +1 -0
- package/types/app/ipex/receive-issuance.d.ts +99 -0
- package/types/app/ipex/receive-issuance.d.ts.map +1 -0
- package/types/app/ipex/unblinding-workflow.d.ts +255 -0
- package/types/app/ipex/unblinding-workflow.d.ts.map +1 -0
- package/types/app/mailbox/ipex-arrival.d.ts +104 -0
- package/types/app/mailbox/ipex-arrival.d.ts.map +1 -0
- package/types/app/mailbox/kel-publisher.d.ts +141 -0
- package/types/app/mailbox/kel-publisher.d.ts.map +1 -0
- package/types/app/mailbox/kel-publishing.d.ts +70 -0
- package/types/app/mailbox/kel-publishing.d.ts.map +1 -0
- package/types/app/mailbox/kel-submission.d.ts +18 -0
- package/types/app/mailbox/kel-submission.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-admin.d.ts +113 -0
- package/types/app/mailbox/mailbox-admin.d.ts.map +1 -0
- package/types/app/mailbox/mailbox-poller.d.ts +92 -3
- package/types/app/mailbox/mailbox-poller.d.ts.map +1 -1
- package/types/app/mailbox/mailboxing.d.ts +4 -1
- package/types/app/mailbox/mailboxing.d.ts.map +1 -1
- package/types/app/multisig/counseling.d.ts +196 -0
- package/types/app/multisig/counseling.d.ts.map +1 -0
- package/types/app/multisig/group-members.d.ts +20 -0
- package/types/app/multisig/group-members.d.ts.map +1 -1
- package/types/app/multisig/grouping.d.ts +39 -20
- package/types/app/multisig/grouping.d.ts.map +1 -1
- package/types/app/multisig/multisig-workflows.d.ts +93 -23
- package/types/app/multisig/multisig-workflows.d.ts.map +1 -1
- package/types/app/multisig/proposals.d.ts +129 -0
- package/types/app/multisig/proposals.d.ts.map +1 -0
- package/types/app/multisig/proposing.d.ts +125 -0
- package/types/app/multisig/proposing.d.ts.map +1 -0
- package/types/app/notifications/notifying.d.ts +1 -1
- package/types/app/notifications/notifying.d.ts.map +1 -1
- package/types/app/notifications/signaling.d.ts +3 -1
- package/types/app/notifications/signaling.d.ts.map +1 -1
- package/types/app/protocol/parsering.d.ts +16 -1
- package/types/app/protocol/parsering.d.ts.map +1 -1
- package/types/app/protocol/protocol-processing.d.ts +9 -1
- package/types/app/protocol/protocol-processing.d.ts.map +1 -1
- package/types/app/queries/query-workflows.d.ts +98 -0
- package/types/app/queries/query-workflows.d.ts.map +1 -0
- package/types/app/runtime/agent-runtime.d.ts +79 -25
- package/types/app/runtime/agent-runtime.d.ts.map +1 -1
- package/types/app/runtime/cue-runtime.d.ts +2 -1
- package/types/app/runtime/cue-runtime.d.ts.map +1 -1
- package/types/app/runtime/delivery-outbox.d.ts +68 -0
- package/types/app/runtime/delivery-outbox.d.ts.map +1 -0
- package/types/app/runtime/doing.d.ts +27 -0
- package/types/app/runtime/doing.d.ts.map +1 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts +74 -0
- package/types/app/runtime/ipex-auxiliaries.d.ts.map +1 -0
- package/types/app/runtime/operation-owners.d.ts +137 -0
- package/types/app/runtime/operation-owners.d.ts.map +1 -0
- package/types/app/runtime/retry-backoff.d.ts +49 -0
- package/types/app/runtime/retry-backoff.d.ts.map +1 -0
- package/types/app/runtime/workflow-contract.d.ts +79 -0
- package/types/app/runtime/workflow-contract.d.ts.map +1 -0
- package/types/app/transport/byte-source.d.ts +13 -10
- package/types/app/transport/byte-source.d.ts.map +1 -1
- package/types/app/transport/cesr-egress.d.ts +21 -7
- package/types/app/transport/cesr-egress.d.ts.map +1 -1
- package/types/app/transport/file-bytes.d.ts +11 -0
- package/types/app/transport/file-bytes.d.ts.map +1 -0
- package/types/app/transport/http-client.d.ts +3 -0
- package/types/app/transport/http-client.d.ts.map +1 -1
- package/types/app/transport/http-messenger.d.ts +15 -10
- package/types/app/transport/http-messenger.d.ts.map +1 -1
- package/types/app/transport/message-source.d.ts +1 -1
- package/types/app/transport/messengering.d.ts +2 -2
- package/types/app/transport/messengering.d.ts.map +1 -1
- package/types/app/transport/node-http-client.d.ts +10 -0
- package/types/app/transport/node-http-client.d.ts.map +1 -0
- package/types/app/transport/tcp-dialer.d.ts +21 -0
- package/types/app/transport/tcp-dialer.d.ts.map +1 -0
- package/types/cli/common/event-completion.d.ts +26 -0
- package/types/cli/common/event-completion.d.ts.map +1 -0
- package/types/cli/common/existing.d.ts.map +1 -1
- package/types/cli/common/runtime-workers.d.ts +23 -0
- package/types/cli/common/runtime-workers.d.ts.map +1 -0
- package/types/cli/credentials/ipex.d.ts.map +1 -1
- package/types/cli/credentials/vc.d.ts +1 -1
- package/types/cli/credentials/vc.d.ts.map +1 -1
- package/types/cli/endpoints/did.d.ts.map +1 -1
- package/types/cli/endpoints/oobi-clean.d.ts.map +1 -1
- package/types/cli/endpoints/oobi.d.ts +3 -1
- package/types/cli/endpoints/oobi.d.ts.map +1 -1
- package/types/cli/identity/challenge.d.ts +1 -1
- package/types/cli/identity/challenge.d.ts.map +1 -1
- package/types/cli/identity/delegate.d.ts +14 -1
- package/types/cli/identity/delegate.d.ts.map +1 -1
- package/types/cli/identity/incept.d.ts.map +1 -1
- package/types/cli/identity/init.d.ts.map +1 -1
- package/types/cli/identity/interact.d.ts.map +1 -1
- package/types/cli/identity/rotate.d.ts.map +1 -1
- package/types/cli/index.d.ts +4 -2
- package/types/cli/index.d.ts.map +1 -1
- package/types/cli/messaging/group-join.d.ts +53 -0
- package/types/cli/messaging/group-join.d.ts.map +1 -0
- package/types/cli/messaging/group-wait.d.ts +34 -0
- package/types/cli/messaging/group-wait.d.ts.map +1 -0
- package/types/cli/messaging/multisig.d.ts +36 -4
- package/types/cli/messaging/multisig.d.ts.map +1 -1
- package/types/cli/messaging/root-copy-lines.d.ts +39 -0
- package/types/cli/messaging/root-copy-lines.d.ts.map +1 -0
- package/types/cli/tools/annotate.d.ts.map +1 -1
- package/types/cli/tools/benchmark.d.ts.map +1 -1
- package/types/cli/tools/db-dump.d.ts.map +1 -1
- package/types/core/bytes.d.ts +2 -0
- package/types/core/bytes.d.ts.map +1 -1
- package/types/core/cues.d.ts +11 -0
- package/types/core/cues.d.ts.map +1 -1
- package/types/core/kel/delegation-ancestry.d.ts +41 -0
- package/types/core/kel/delegation-ancestry.d.ts.map +1 -0
- package/types/core/kel/eventing.d.ts.map +1 -1
- package/types/core/kel/kever.d.ts +5 -4
- package/types/core/kel/kever.d.ts.map +1 -1
- package/types/core/mailbox/kram-policy.d.ts +14 -0
- package/types/core/mailbox/kram-policy.d.ts.map +1 -1
- package/types/core/mailbox/kram-pruning.d.ts +1 -3
- package/types/core/mailbox/kram-pruning.d.ts.map +1 -1
- package/types/core/mailbox/kraming.d.ts +1 -1
- package/types/core/mailbox/kraming.d.ts.map +1 -1
- package/types/core/records.d.ts +61 -0
- package/types/core/records.d.ts.map +1 -1
- package/types/core/routing.d.ts +6 -0
- package/types/core/routing.d.ts.map +1 -1
- package/types/db/basing.d.ts +22 -25
- package/types/db/basing.d.ts.map +1 -1
- package/types/db/core/dber.d.ts +505 -0
- package/types/db/core/dber.d.ts.map +1 -0
- package/types/db/core/index.d.ts +4 -2
- package/types/db/core/index.d.ts.map +1 -1
- package/types/db/core/indexeddb-persistence.d.ts +59 -0
- package/types/db/core/indexeddb-persistence.d.ts.map +1 -0
- package/types/db/core/lmdb-opener.d.ts +17 -0
- package/types/db/core/lmdb-opener.d.ts.map +1 -0
- package/types/db/core/lmdber.d.ts +60 -383
- package/types/db/core/lmdber.d.ts.map +1 -1
- package/types/db/core/memstore.d.ts +129 -0
- package/types/db/core/memstore.d.ts.map +1 -0
- package/types/db/core/path-manager.d.ts +22 -45
- package/types/db/core/path-manager.d.ts.map +1 -1
- package/types/db/core/store-owner.d.ts +59 -0
- package/types/db/core/store-owner.d.ts.map +1 -0
- package/types/db/core/webdber.d.ts +127 -0
- package/types/db/core/webdber.d.ts.map +1 -0
- package/types/db/escrowing.d.ts +3 -3
- package/types/db/escrowing.d.ts.map +1 -1
- package/types/db/exchange/exchange-nests.d.ts.map +1 -1
- package/types/db/indexeddb.d.ts +37 -0
- package/types/db/indexeddb.d.ts.map +1 -0
- package/types/db/keeping.d.ts +14 -25
- package/types/db/keeping.d.ts.map +1 -1
- package/types/db/koming.d.ts +7 -8
- package/types/db/koming.d.ts.map +1 -1
- package/types/db/lmdb-stores.d.ts +45 -0
- package/types/db/lmdb-stores.d.ts.map +1 -0
- package/types/db/lmdb.d.ts +7 -0
- package/types/db/lmdb.d.ts.map +1 -0
- package/types/db/mailbox/mailboxing.d.ts +7 -21
- package/types/db/mailbox/mailboxing.d.ts.map +1 -1
- package/types/db/noting.d.ts +7 -12
- package/types/db/noting.d.ts.map +1 -1
- package/types/db/reger.d.ts +7 -11
- package/types/db/reger.d.ts.map +1 -1
- package/types/db/replay/witness-replay.d.ts +0 -2
- package/types/db/replay/witness-replay.d.ts.map +1 -1
- package/types/db/store-lock.d.ts +72 -0
- package/types/db/store-lock.d.ts.map +1 -0
- package/types/db/subing.d.ts +24 -25
- package/types/db/subing.d.ts.map +1 -1
- package/types/npm/db-indexeddb.d.ts +4 -0
- package/types/npm/db-indexeddb.d.ts.map +1 -0
- package/types/npm/db-lmdb.d.ts +4 -0
- package/types/npm/db-lmdb.d.ts.map +1 -0
- package/types/npm/runtime-node.d.ts +4 -0
- package/types/npm/runtime-node.d.ts.map +1 -0
- package/types/npm/runtime-web.d.ts +4 -0
- package/types/npm/runtime-web.d.ts.map +1 -0
- package/types/runtime/index.d.ts +48 -14
- package/types/runtime/index.d.ts.map +1 -1
- package/types/runtime/node.d.ts +15 -0
- package/types/runtime/node.d.ts.map +1 -0
- package/types/runtime/web/output-barrier.d.ts +30 -0
- package/types/runtime/web/output-barrier.d.ts.map +1 -0
- package/types/runtime/web/persistent-storage.d.ts +36 -0
- package/types/runtime/web/persistent-storage.d.ts.map +1 -0
- package/types/runtime/web.d.ts +11 -0
- package/types/runtime/web.d.ts.map +1 -0
- package/types/vdr/tel-publication.d.ts +6 -0
- package/types/vdr/tel-publication.d.ts.map +1 -1
- package/types/version.d.ts +2 -2
- package/esm/keri/npm/src/acdc/relating.js +0 -59
- package/esm/keri/npm/src/cli/common/tel-completion.js +0 -24
- package/esm/keri/npm/src/db/baser-defaults.js +0 -11
- package/types/acdc/relating.d.ts +0 -21
- package/types/acdc/relating.d.ts.map +0 -1
- package/types/cli/common/tel-completion.d.ts +0 -8
- package/types/cli/common/tel-completion.d.ts.map +0 -1
- package/types/db/baser-defaults.d.ts +0 -5
- package/types/db/baser-defaults.d.ts.map +0 -1
|
@@ -0,0 +1,1062 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend-neutral store contract shared by every `keri-ts` database backend.
|
|
3
|
+
*
|
|
4
|
+
* ADR-0015 owns the semantics. Backends supply row access and transactions;
|
|
5
|
+
* the ordinal, insertion-ordered set and insertion-ordered duplicate families
|
|
6
|
+
* below are built only on those primitives, so every backend shares them.
|
|
7
|
+
*/
|
|
8
|
+
import { b, bytesEqual, bytesHex, t } from "cesr-ts";
|
|
9
|
+
import { onKey, splitOnKey, suffix, unsuffix } from "./keys.js";
|
|
10
|
+
/** The pinned lmdb-js limit on keys and dupsort values, shared by every backend (ADR-0015). */
|
|
11
|
+
export const MAX_KEY_BYTES = 1978;
|
|
12
|
+
/** Default separator used by ordinal/suffix key helpers (`onKey`, `suffix`). */
|
|
13
|
+
const DOT_SEP = b(".");
|
|
14
|
+
/**
|
|
15
|
+
* Hex chars used for IoDup insertion ordinal prefix.
|
|
16
|
+
* Does not include trailing separator.
|
|
17
|
+
*/
|
|
18
|
+
const IODUP_PROEM_HEX_SIZE = 32;
|
|
19
|
+
/**
|
|
20
|
+
* Full IoDup proem size:
|
|
21
|
+
* 32-hex ordinal + trailing `.` separator.
|
|
22
|
+
*/
|
|
23
|
+
const IODUP_PROEM_SIZE = 33;
|
|
24
|
+
/**
|
|
25
|
+
* Dedupe binary values while preserving first-seen order.
|
|
26
|
+
* Example: `[a, b, a] -> [a, b]`.
|
|
27
|
+
*/
|
|
28
|
+
function asUniqueVals(vals) {
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
const out = [];
|
|
31
|
+
for (const val of vals) {
|
|
32
|
+
const key = bytesHex(val);
|
|
33
|
+
if (seen.has(key)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
seen.add(key);
|
|
37
|
+
out.push(val);
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
/** Build IoDup ordering proem bytes (`000...00a.` for index `10`). */
|
|
42
|
+
function iDupProem(index) {
|
|
43
|
+
return b(`${index.toString(16).padStart(IODUP_PROEM_HEX_SIZE, "0")}.`);
|
|
44
|
+
}
|
|
45
|
+
/** Prefix value bytes with IoDup ordering proem for insertion-order semantics. */
|
|
46
|
+
function withIoDupProem(index, val) {
|
|
47
|
+
const proem = iDupProem(index);
|
|
48
|
+
const out = new Uint8Array(proem.length + val.length);
|
|
49
|
+
out.set(proem, 0);
|
|
50
|
+
out.set(val, proem.length);
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
/** Strip IoDup ordering proem from a stored duplicate value. */
|
|
54
|
+
function stripIoDupProem(val) {
|
|
55
|
+
return val.length >= IODUP_PROEM_SIZE
|
|
56
|
+
? val.slice(IODUP_PROEM_SIZE)
|
|
57
|
+
: new Uint8Array(0);
|
|
58
|
+
}
|
|
59
|
+
/** Parse IoDup insertion ordinal from proem-prefixed stored value. */
|
|
60
|
+
function parseIoDupOrdinal(val) {
|
|
61
|
+
if (val.length < IODUP_PROEM_HEX_SIZE) {
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
const parsed = Number.parseInt(t(val.slice(0, IODUP_PROEM_HEX_SIZE)), 16);
|
|
65
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Shared base for every store backend.
|
|
69
|
+
*
|
|
70
|
+
* Subclasses implement the abstract row access. Everything concrete here must
|
|
71
|
+
* stay free of backend types so a new backend inherits identical family
|
|
72
|
+
* behavior.
|
|
73
|
+
*/
|
|
74
|
+
export class BaseDBer {
|
|
75
|
+
/*
|
|
76
|
+
* Ordinal-key family (`On*`)
|
|
77
|
+
* Logical shape: one logical key -> many values via fixed-width ordinal in key.
|
|
78
|
+
* Multiplicity: synthetic, stored in keyspace as `key.<on>`.
|
|
79
|
+
* Ordering: lexicographic key order matches numeric ordinal order.
|
|
80
|
+
* Parity status: direct KERIpy analogs plus TS rename conveniences.
|
|
81
|
+
*/
|
|
82
|
+
/**
|
|
83
|
+
* Write `val` at the ordinal key `onKey(key, on)` only when absent.
|
|
84
|
+
*
|
|
85
|
+
* The ordinal is encoded into the physical key as a fixed-width 32-hex suffix
|
|
86
|
+
* so LMDB key order matches ordinal order. Mirrors KERIpy `putOnVal`.
|
|
87
|
+
*/
|
|
88
|
+
putOnVal(db, key, on = 0, val = null, sep = DOT_SEP) {
|
|
89
|
+
if (val === null) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
return this.putVal(db, onKey(key, on, sep), val);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Write `val` at `onKey(key, on)`, overwriting any existing value.
|
|
96
|
+
*
|
|
97
|
+
* TypeScript-local rename of KERIpy `setOnVal`.
|
|
98
|
+
*/
|
|
99
|
+
pinOnVal(db, key, on = 0, val = null, sep = DOT_SEP) {
|
|
100
|
+
if (!key.length || val === null) {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
return this.setVal(db, onKey(key, on, sep), val);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Append `val` at the next ordinal slot for `key`.
|
|
107
|
+
*
|
|
108
|
+
* This scans backward from the `key.MaxON` boundary to find the current tail,
|
|
109
|
+
* then writes at the next ordinal. Returns the appended ordinal. Mirrors
|
|
110
|
+
* KERIpy `appendOnVal`.
|
|
111
|
+
*/
|
|
112
|
+
appendOnVal(db, key, val, sep = DOT_SEP) {
|
|
113
|
+
this.assertOpen();
|
|
114
|
+
if (!key.length || val === null) {
|
|
115
|
+
throw new Error(`Bad append parameter: key=${Array.from(key)} val=${val}`);
|
|
116
|
+
}
|
|
117
|
+
// KERIpy parity: seek from key.MaxON boundary and step back to the tail
|
|
118
|
+
// key for this prefix (if any), rather than scanning key.000... upward.
|
|
119
|
+
const maxOnSuffix = b("f".repeat(32));
|
|
120
|
+
const start = new Uint8Array(key.length + sep.length + maxOnSuffix.length);
|
|
121
|
+
start.set(key, 0);
|
|
122
|
+
start.set(sep, key.length);
|
|
123
|
+
start.set(maxOnSuffix, key.length + sep.length);
|
|
124
|
+
let nextOn = 0;
|
|
125
|
+
for (const entry of this.scan(db, { start, reverse: true, limit: 1 })) {
|
|
126
|
+
const tailOnKey = entry.key;
|
|
127
|
+
const [ckey, cn] = splitOnKey(tailOnKey, sep);
|
|
128
|
+
if (!bytesEqual(ckey, key)) {
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
if (bytesEqual(tailOnKey, start)) {
|
|
132
|
+
throw new Error(`Number part cn=${cn} for key part ckey=${Array.from(ckey)} exceeds maximum size.`);
|
|
133
|
+
}
|
|
134
|
+
nextOn = cn + 1;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
const targetKey = onKey(key, nextOn, sep);
|
|
138
|
+
const added = this.putVal(db, targetKey, val);
|
|
139
|
+
if (added) {
|
|
140
|
+
return nextOn;
|
|
141
|
+
}
|
|
142
|
+
// Some compat/interop flows still surface LMDB-js range behavior where the
|
|
143
|
+
// reverse tail probe fails to observe the existing highest ordinal entry.
|
|
144
|
+
// Fall back to counting the live branch and append at that count instead of
|
|
145
|
+
// failing a logically valid append.
|
|
146
|
+
const fallbackOn = this.cntOnAll(db, key, 0, sep);
|
|
147
|
+
if (fallbackOn !== nextOn) {
|
|
148
|
+
const fallbackAdded = this.putVal(db, onKey(key, fallbackOn, sep), val);
|
|
149
|
+
if (fallbackAdded) {
|
|
150
|
+
return fallbackOn;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
throw new Error(`Failed appending value at key=${Array.from(key)}.`);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* TypeScript-only convenience returning the exact `(key, on, val)` triple.
|
|
157
|
+
*
|
|
158
|
+
* Returns `null` when that exact ordinal entry is missing.
|
|
159
|
+
*/
|
|
160
|
+
getOnItem(db, key, on = 0, sep = DOT_SEP) {
|
|
161
|
+
const val = this.getOnVal(db, key, on, sep);
|
|
162
|
+
return val ? [key, on, val] : null;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Fetch the value stored exactly at `onKey(key, on)`.
|
|
166
|
+
*
|
|
167
|
+
* Returns `null` when the exact ordinal entry is missing. Empty logical keys
|
|
168
|
+
* are treated as absent. Mirrors KERIpy `getOnVal`.
|
|
169
|
+
*/
|
|
170
|
+
getOnVal(db, key, on = 0, sep = DOT_SEP) {
|
|
171
|
+
if (!key.length) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
return this.getVal(db, onKey(key, on, sep));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Remove the value stored exactly at `onKey(key, on)`.
|
|
178
|
+
*
|
|
179
|
+
* Empty logical keys return `false`. TypeScript-local rename of KERIpy
|
|
180
|
+
* `delOnVal`.
|
|
181
|
+
*/
|
|
182
|
+
remOn(db, key, on = 0, sep = DOT_SEP) {
|
|
183
|
+
if (!key.length) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
return this.delVal(db, onKey(key, on, sep));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Remove all ordinal entries for `key` starting at ordinal `on`.
|
|
190
|
+
*
|
|
191
|
+
* Empty `key` removes the whole DB branch. TypeScript-only convenience built
|
|
192
|
+
* on the same ordinal-key semantics as KERIpy `delOnVal`.
|
|
193
|
+
*/
|
|
194
|
+
remOnAll(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
195
|
+
if (!key.length) {
|
|
196
|
+
return this.delTop(db, new Uint8Array(0));
|
|
197
|
+
}
|
|
198
|
+
this.assertOpen();
|
|
199
|
+
const start = onKey(key, on, sep);
|
|
200
|
+
const keys = [];
|
|
201
|
+
for (const entry of this.scan(db, { start })) {
|
|
202
|
+
const ckey = entry.key;
|
|
203
|
+
const [top] = splitOnKey(ckey, sep);
|
|
204
|
+
if (!bytesEqual(top, key)) {
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
keys.push(new Uint8Array(ckey));
|
|
208
|
+
}
|
|
209
|
+
if (!keys.length) {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
this.transaction(() => {
|
|
213
|
+
for (const k of keys) {
|
|
214
|
+
this.removeRow(db, k);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Count ordinal-keyed entries for `key` starting at ordinal `on`.
|
|
221
|
+
*
|
|
222
|
+
* Empty `key` counts the whole DB. TypeScript-local rename of KERIpy
|
|
223
|
+
* `cntOnVals`.
|
|
224
|
+
*/
|
|
225
|
+
cntOnAll(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
226
|
+
this.assertOpen();
|
|
227
|
+
const start = key.length ? onKey(key, on, sep) : new Uint8Array(0);
|
|
228
|
+
let count = 0;
|
|
229
|
+
for (const entry of this.scan(db, { start })) {
|
|
230
|
+
const ckey = entry.key;
|
|
231
|
+
const [top] = splitOnKey(ckey, sep);
|
|
232
|
+
if (key.length && !bytesEqual(top, key)) {
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
count += 1;
|
|
236
|
+
}
|
|
237
|
+
return count;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Iterate `(key, on, val)` triples whose physical keys begin with branch `top`.
|
|
241
|
+
*
|
|
242
|
+
* This is the ordinal-key version of `getTopItemIter`, so branch membership is
|
|
243
|
+
* still a lexicographic key-prefix concept. TypeScript-only convenience.
|
|
244
|
+
*/
|
|
245
|
+
*getOnTopItemIter(db, top = new Uint8Array(0), sep = DOT_SEP) {
|
|
246
|
+
for (const [onkey, val] of this.getTopItemIter(db, top)) {
|
|
247
|
+
const [key, on] = splitOnKey(onkey, sep);
|
|
248
|
+
yield [key, on, val];
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Iterate `(key, on, val)` triples for ordinals `>= on`.
|
|
253
|
+
*
|
|
254
|
+
* Empty `key` iterates the whole DB. Ordering follows the fixed-width ordinal
|
|
255
|
+
* encoded in the key. TypeScript-local rename of KERIpy `getOnItemIter`.
|
|
256
|
+
*/
|
|
257
|
+
*getOnAllItemIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
258
|
+
this.assertOpen();
|
|
259
|
+
const start = key.length ? onKey(key, on, sep) : new Uint8Array(0);
|
|
260
|
+
for (const entry of this.scan(db, { start })) {
|
|
261
|
+
const ckey = entry.key;
|
|
262
|
+
const cval = entry.value;
|
|
263
|
+
const [top, cn] = splitOnKey(ckey, sep);
|
|
264
|
+
if (key.length && !bytesEqual(top, key)) {
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
yield [top, cn, cval];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/*
|
|
271
|
+
* Synthetic insertion-ordered set family (`IoSet*`)
|
|
272
|
+
* Logical shape: one logical key -> many values without dupsort.
|
|
273
|
+
* Multiplicity: synthetic, stored in keyspace as `key.<ion>`.
|
|
274
|
+
* Ordering: hidden fixed-width insertion suffix in the physical key.
|
|
275
|
+
* Parity status: direct KERIpy analogs with TS naming tweaks.
|
|
276
|
+
*/
|
|
277
|
+
/**
|
|
278
|
+
* Add each unique value in `vals` to the insertion-ordered set at `key`.
|
|
279
|
+
*
|
|
280
|
+
* This emulates duplicate-like behavior in keyspace, not native LMDB dupsort:
|
|
281
|
+
* values are stored under hidden suffixed keys `key.<ion>`. Existing logical
|
|
282
|
+
* members are skipped, new members append at the next suffix. Mirrors KERIpy
|
|
283
|
+
* `putIoSetVals`.
|
|
284
|
+
*/
|
|
285
|
+
putIoSetVals(db, key, vals, sep = DOT_SEP) {
|
|
286
|
+
if (!key.length || vals === null) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
const uniqueVals = asUniqueVals(vals);
|
|
290
|
+
if (!uniqueVals.length) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
const existing = new Set();
|
|
294
|
+
let ion = 0;
|
|
295
|
+
const start = suffix(key, 0, sep);
|
|
296
|
+
for (const entry of this.scan(db, { start })) {
|
|
297
|
+
const iokey = entry.key;
|
|
298
|
+
const cval = entry.value;
|
|
299
|
+
const [ckey, cion] = unsuffix(iokey, sep);
|
|
300
|
+
if (!bytesEqual(ckey, key)) {
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
existing.add(bytesHex(cval));
|
|
304
|
+
ion = cion + 1;
|
|
305
|
+
}
|
|
306
|
+
const insert = uniqueVals.filter((val) => !existing.has(bytesHex(val)));
|
|
307
|
+
if (!insert.length) {
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
this.assertOpen();
|
|
311
|
+
this.transaction(() => {
|
|
312
|
+
for (const [index, val] of insert.entries()) {
|
|
313
|
+
this.putRow(db, suffix(key, ion + index, sep), val);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Replace the insertion-ordered set at `key` with the provided unique values.
|
|
320
|
+
*
|
|
321
|
+
* This clears the existing synthetic key run for `key`, then rewrites fresh
|
|
322
|
+
* hidden suffixes from zero. TypeScript-local rename of KERIpy `setIoSetVals`.
|
|
323
|
+
*/
|
|
324
|
+
pinIoSetVals(db, key, vals, sep = DOT_SEP) {
|
|
325
|
+
if (!key.length || vals === null) {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
const uniqueVals = asUniqueVals(vals);
|
|
329
|
+
if (!uniqueVals.length) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
this.remIoSet(db, key, sep);
|
|
333
|
+
this.assertOpen();
|
|
334
|
+
this.transaction(() => {
|
|
335
|
+
for (const [index, val] of uniqueVals.entries()) {
|
|
336
|
+
this.putRow(db, suffix(key, index, sep), val);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Add one value to the insertion-ordered set at `key` if it is not present.
|
|
343
|
+
*
|
|
344
|
+
* Membership is checked by scanning the synthetic key run for `key`; new
|
|
345
|
+
* values append at the next hidden suffix. Mirrors KERIpy `addIoSetVal`.
|
|
346
|
+
*/
|
|
347
|
+
addIoSetVal(db, key, val, sep = DOT_SEP) {
|
|
348
|
+
this.assertOpen();
|
|
349
|
+
if (!key.length || val === null) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
let ion = 0;
|
|
353
|
+
const valHex = bytesHex(val);
|
|
354
|
+
const start = suffix(key, 0, sep);
|
|
355
|
+
for (const entry of this.scan(db, { start })) {
|
|
356
|
+
const iokey = entry.key;
|
|
357
|
+
const cval = entry.value;
|
|
358
|
+
const [ckey, cion] = unsuffix(iokey, sep);
|
|
359
|
+
if (!bytesEqual(ckey, key)) {
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
if (bytesHex(cval) === valHex) {
|
|
363
|
+
return false;
|
|
364
|
+
}
|
|
365
|
+
ion = cion + 1;
|
|
366
|
+
}
|
|
367
|
+
return this.putVal(db, suffix(key, ion, sep), val);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Iterate `(key, val)` pairs for the insertion-ordered set at `key`.
|
|
371
|
+
*
|
|
372
|
+
* Iteration starts at hidden insertion ordinal `ion`. Returned keys are the
|
|
373
|
+
* logical effective key with the hidden suffix removed. TypeScript-local item
|
|
374
|
+
* variant corresponding to KERIpy `getIoSetValsIter`.
|
|
375
|
+
*/
|
|
376
|
+
*getIoSetItemIter(db, key, ion = 0, sep = DOT_SEP) {
|
|
377
|
+
this.assertOpen();
|
|
378
|
+
if (!key.length) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
const start = suffix(key, ion, sep);
|
|
382
|
+
for (const entry of this.scan(db, { start })) {
|
|
383
|
+
const iokey = entry.key;
|
|
384
|
+
const cval = entry.value;
|
|
385
|
+
const [ckey] = unsuffix(iokey, sep);
|
|
386
|
+
if (!bytesEqual(ckey, key)) {
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
yield [ckey, cval];
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Return the last logical set member at `key`, or `null`.
|
|
394
|
+
*
|
|
395
|
+
* "Last" means the entry stored under the greatest hidden insertion suffix,
|
|
396
|
+
* not the lexicographically greatest value bytes. TypeScript-local item
|
|
397
|
+
* variant corresponding to KERIpy `getIoSetValLast`.
|
|
398
|
+
*/
|
|
399
|
+
getIoSetLastItem(db, key, sep = DOT_SEP) {
|
|
400
|
+
let last = null;
|
|
401
|
+
for (const item of this.getIoSetItemIter(db, key, 0, sep)) {
|
|
402
|
+
last = item;
|
|
403
|
+
}
|
|
404
|
+
return last;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Remove all insertion-ordered set members at `key`.
|
|
408
|
+
*
|
|
409
|
+
* This deletes the full synthetic key run for the effective key. TypeScript-
|
|
410
|
+
* local rename of KERIpy `delIoSetVals`.
|
|
411
|
+
*/
|
|
412
|
+
remIoSet(db, key, sep = DOT_SEP) {
|
|
413
|
+
if (!key.length) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
this.assertOpen();
|
|
417
|
+
const keys = [];
|
|
418
|
+
const start = suffix(key, 0, sep);
|
|
419
|
+
for (const entry of this.scan(db, { start })) {
|
|
420
|
+
const iokey = entry.key;
|
|
421
|
+
const [ckey] = unsuffix(iokey, sep);
|
|
422
|
+
if (!bytesEqual(ckey, key)) {
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
keys.push(new Uint8Array(iokey));
|
|
426
|
+
}
|
|
427
|
+
if (!keys.length) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
this.transaction(() => {
|
|
431
|
+
for (const iokey of keys) {
|
|
432
|
+
this.removeRow(db, iokey);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Remove one logical set member at `key`, or all members when `val` is `null`.
|
|
439
|
+
*
|
|
440
|
+
* Delete-by-value requires a linear search because the caller does not know
|
|
441
|
+
* the hidden insertion suffix. As in KERIpy, suffix ordinals can grow
|
|
442
|
+
* monotonically over time after deletes and reinserts. TypeScript-local rename
|
|
443
|
+
* of KERIpy `delIoSetVal`.
|
|
444
|
+
*/
|
|
445
|
+
remIoSetVal(db, key, val = null, sep = DOT_SEP) {
|
|
446
|
+
if (val === null) {
|
|
447
|
+
return this.remIoSet(db, key, sep);
|
|
448
|
+
}
|
|
449
|
+
if (!key.length) {
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
this.assertOpen();
|
|
453
|
+
const valHex = bytesHex(val);
|
|
454
|
+
let removeKey = null;
|
|
455
|
+
const start = suffix(key, 0, sep);
|
|
456
|
+
for (const entry of this.scan(db, { start })) {
|
|
457
|
+
const iokey = entry.key;
|
|
458
|
+
const cval = entry.value;
|
|
459
|
+
const [ckey] = unsuffix(iokey, sep);
|
|
460
|
+
if (!bytesEqual(ckey, key)) {
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
if (bytesHex(cval) === valHex) {
|
|
464
|
+
removeKey = new Uint8Array(iokey);
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (!removeKey) {
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
this.transaction(() => {
|
|
472
|
+
this.removeRow(db, removeKey);
|
|
473
|
+
});
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Count logical set members at `key` starting from hidden insertion ordinal `ion`.
|
|
478
|
+
*
|
|
479
|
+
* TypeScript-local item-count variant corresponding to KERIpy `cntIoSetVals`.
|
|
480
|
+
*/
|
|
481
|
+
cntIoSet(db, key, ion = 0, sep = DOT_SEP) {
|
|
482
|
+
if (!key.length) {
|
|
483
|
+
return 0;
|
|
484
|
+
}
|
|
485
|
+
let count = 0;
|
|
486
|
+
for (const _ of this.getIoSetItemIter(db, key, ion, sep)) {
|
|
487
|
+
count += 1;
|
|
488
|
+
}
|
|
489
|
+
return count;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Iterate `(key, val)` pairs for all synthetic-set entries in branch `top`.
|
|
493
|
+
*
|
|
494
|
+
* Branch membership is still a lexicographic key-prefix scan over the
|
|
495
|
+
* physical suffixed keys; returned keys have the hidden insertion suffix
|
|
496
|
+
* removed. Mirrors KERIpy `getTopIoSetItemIter`.
|
|
497
|
+
*/
|
|
498
|
+
*getTopIoSetItemIter(db, top = new Uint8Array(0), sep = DOT_SEP) {
|
|
499
|
+
for (const [iokey, val] of this.getTopItemIter(db, top)) {
|
|
500
|
+
const [key] = unsuffix(iokey, sep);
|
|
501
|
+
yield [key, val];
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Iterate the last `(key, val)` member for each effective io-set key.
|
|
506
|
+
*
|
|
507
|
+
* Empty `key` iterates the whole DB. "Last" is determined by hidden suffix
|
|
508
|
+
* order. TypeScript-local item variant built from KERIpy `getIoSetValLast`
|
|
509
|
+
* and branch iteration semantics.
|
|
510
|
+
*/
|
|
511
|
+
*getIoSetLastItemIterAll(db, key = new Uint8Array(0), sep = DOT_SEP) {
|
|
512
|
+
this.assertOpen();
|
|
513
|
+
const start = key.length ? suffix(key, 0, sep) : undefined;
|
|
514
|
+
let last = null;
|
|
515
|
+
let lkey = null;
|
|
516
|
+
for (const entry of this.scan(db, { start })) {
|
|
517
|
+
const iokey = entry.key;
|
|
518
|
+
const cval = entry.value;
|
|
519
|
+
const [ckey] = unsuffix(iokey, sep);
|
|
520
|
+
if (lkey === null) {
|
|
521
|
+
lkey = ckey;
|
|
522
|
+
}
|
|
523
|
+
if (!bytesEqual(ckey, lkey)) {
|
|
524
|
+
if (last) {
|
|
525
|
+
yield last;
|
|
526
|
+
}
|
|
527
|
+
lkey = ckey;
|
|
528
|
+
}
|
|
529
|
+
last = [ckey, cval];
|
|
530
|
+
}
|
|
531
|
+
if (last) {
|
|
532
|
+
yield last;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Iterate only the last logical values for each effective io-set key `>= key`.
|
|
537
|
+
*
|
|
538
|
+
* TypeScript-only convenience built on `getIoSetLastItemIterAll`.
|
|
539
|
+
*/
|
|
540
|
+
*getIoSetLastIterAll(db, key = new Uint8Array(0), sep = DOT_SEP) {
|
|
541
|
+
for (const [_, val] of this.getIoSetLastItemIterAll(db, key, sep)) {
|
|
542
|
+
yield val;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
/*
|
|
546
|
+
* Ordinal synthetic insertion-ordered set family (`OnIoSet*`)
|
|
547
|
+
* Logical shape: ordinal buckets, each bucket holding an insertion-ordered set.
|
|
548
|
+
* Multiplicity: synthetic, stored in keyspace as `key.<on>.<ion>`.
|
|
549
|
+
* Ordering: exposed fixed-width ordinal in the key, then hidden insertion suffix.
|
|
550
|
+
* Parity status: TypeScript-only extension. KERIpy exposes `IoSet*` and
|
|
551
|
+
* `OnIoDup*`, but not `OnIoSet*`. This exists as extension surface for
|
|
552
|
+
* ordinal buckets + insertion-ordered set semantics without dupsort
|
|
553
|
+
* constraints, and currently has no production callers.
|
|
554
|
+
*/
|
|
555
|
+
/**
|
|
556
|
+
* TypeScript-only extension. Add set members at ordinal effective key `onKey(key, on)`.
|
|
557
|
+
*
|
|
558
|
+
* This is the `On` + `IoSet` composition: exposed ordinal in keyspace, hidden
|
|
559
|
+
* insertion suffix inside that ordinal bucket.
|
|
560
|
+
*/
|
|
561
|
+
putOnIoSetVals(db, key, on = 0, vals = null, sep = DOT_SEP) {
|
|
562
|
+
if (!key.length) {
|
|
563
|
+
return false;
|
|
564
|
+
}
|
|
565
|
+
return this.putIoSetVals(db, onKey(key, on, sep), vals, sep);
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* TypeScript-only extension. Replace set members at ordinal effective key.
|
|
569
|
+
*
|
|
570
|
+
* This is the ordinal-bucketed counterpart to `pinIoSetVals`.
|
|
571
|
+
*/
|
|
572
|
+
pinOnIoSetVals(db, key, on = 0, vals = null, sep = DOT_SEP) {
|
|
573
|
+
if (!key.length) {
|
|
574
|
+
return false;
|
|
575
|
+
}
|
|
576
|
+
return this.pinIoSetVals(db, onKey(key, on, sep), vals, sep);
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* TypeScript-only extension. Append a new ordinal bucket for `key`.
|
|
580
|
+
*
|
|
581
|
+
* Returns the newly appended exposed ordinal. Within that bucket, the values
|
|
582
|
+
* are stored as an `IoSet` using hidden insertion suffixes.
|
|
583
|
+
*/
|
|
584
|
+
appendOnIoSetVals(db, key, vals, sep = DOT_SEP) {
|
|
585
|
+
this.assertOpen();
|
|
586
|
+
if (!key.length || vals === null) {
|
|
587
|
+
throw new Error(`Bad append parameter: key=${Array.from(key)} vals=${vals}`);
|
|
588
|
+
}
|
|
589
|
+
let on = 0;
|
|
590
|
+
const start = suffix(onKey(key, 0, sep), 0, sep);
|
|
591
|
+
for (const entry of this.scan(db, { start })) {
|
|
592
|
+
const iokey = entry.key;
|
|
593
|
+
const [onkey] = unsuffix(iokey, sep);
|
|
594
|
+
const [ckey, con] = splitOnKey(onkey, sep);
|
|
595
|
+
if (!bytesEqual(ckey, key)) {
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
on = con + 1;
|
|
599
|
+
}
|
|
600
|
+
if (!this.putOnIoSetVals(db, key, on, vals, sep)) {
|
|
601
|
+
throw new Error(`Failed appending set values at key=${Array.from(key)}.`);
|
|
602
|
+
}
|
|
603
|
+
return on;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* TypeScript-only extension. Add one set member inside an ordinal bucket.
|
|
607
|
+
*
|
|
608
|
+
* This is the ordinal-bucketed counterpart to `addIoSetVal`.
|
|
609
|
+
*/
|
|
610
|
+
addOnIoSetVal(db, key, on = 0, val = null, sep = DOT_SEP) {
|
|
611
|
+
return this.addIoSetVal(db, onKey(key, on, sep), val, sep);
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* TypeScript-only extension. Iterate `(key, on, val)` members at one exact ordinal.
|
|
615
|
+
*
|
|
616
|
+
* Ordering inside the bucket follows the hidden insertion suffix.
|
|
617
|
+
*/
|
|
618
|
+
*getOnIoSetItemIter(db, key, on = 0, ion = 0, sep = DOT_SEP) {
|
|
619
|
+
for (const [onkey, val] of this.getIoSetItemIter(db, onKey(key, on, sep), ion, sep)) {
|
|
620
|
+
const [k, o] = splitOnKey(onkey, sep);
|
|
621
|
+
yield [k, o, val];
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* TypeScript-only extension. Fetch the last member in one ordinal bucket.
|
|
626
|
+
*
|
|
627
|
+
* Returns `null` when that exact ordinal bucket is empty or missing.
|
|
628
|
+
*/
|
|
629
|
+
getOnIoSetLastItem(db, key, on = 0, sep = DOT_SEP) {
|
|
630
|
+
const last = this.getIoSetLastItem(db, onKey(key, on, sep), sep);
|
|
631
|
+
if (!last) {
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
const [onkey, val] = last;
|
|
635
|
+
const [k, o] = splitOnKey(onkey, sep);
|
|
636
|
+
return [k, o, val];
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* TypeScript-only extension. Remove one member from an ordinal bucket.
|
|
640
|
+
*
|
|
641
|
+
* When `val` is `null`, removes the whole ordinal bucket.
|
|
642
|
+
*/
|
|
643
|
+
remOnIoSetVal(db, key, on = 0, val = null, sep = DOT_SEP) {
|
|
644
|
+
return this.remIoSetVal(db, onKey(key, on, sep), val, sep);
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* TypeScript-only extension. Remove all ordinal buckets for `key` from `on` onward.
|
|
648
|
+
*
|
|
649
|
+
* Empty `key` removes the whole DB branch.
|
|
650
|
+
*/
|
|
651
|
+
remOnAllIoSet(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
652
|
+
if (!key.length) {
|
|
653
|
+
return this.delTop(db, new Uint8Array(0));
|
|
654
|
+
}
|
|
655
|
+
this.assertOpen();
|
|
656
|
+
const start = suffix(onKey(key, on, sep), 0, sep);
|
|
657
|
+
const keys = [];
|
|
658
|
+
for (const entry of this.scan(db, { start })) {
|
|
659
|
+
const iokey = entry.key;
|
|
660
|
+
const [onkey] = unsuffix(iokey, sep);
|
|
661
|
+
const [ckey] = splitOnKey(onkey, sep);
|
|
662
|
+
if (!bytesEqual(ckey, key)) {
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
keys.push(new Uint8Array(iokey));
|
|
666
|
+
}
|
|
667
|
+
if (!keys.length) {
|
|
668
|
+
return false;
|
|
669
|
+
}
|
|
670
|
+
this.transaction(() => {
|
|
671
|
+
for (const iokey of keys) {
|
|
672
|
+
this.removeRow(db, iokey);
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
return true;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* TypeScript-only extension. Count members in one ordinal bucket from insertion ordinal `ion`.
|
|
679
|
+
*/
|
|
680
|
+
cntOnIoSet(db, key, on = 0, ion = 0, sep = DOT_SEP) {
|
|
681
|
+
return this.cntIoSet(db, onKey(key, on, sep), ion, sep);
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* TypeScript-only extension. Count all members across ordinal buckets for `key` from `on` onward.
|
|
685
|
+
*/
|
|
686
|
+
cntOnAllIoSet(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
687
|
+
this.assertOpen();
|
|
688
|
+
if (!key.length) {
|
|
689
|
+
return this.cntAll(db);
|
|
690
|
+
}
|
|
691
|
+
let count = 0;
|
|
692
|
+
const start = suffix(onKey(key, on, sep), 0, sep);
|
|
693
|
+
for (const entry of this.scan(db, { start })) {
|
|
694
|
+
const [onkey] = unsuffix(entry.key, sep);
|
|
695
|
+
const [ckey] = splitOnKey(onkey, sep);
|
|
696
|
+
if (!bytesEqual(ckey, key)) {
|
|
697
|
+
break;
|
|
698
|
+
}
|
|
699
|
+
count += 1;
|
|
700
|
+
}
|
|
701
|
+
return count;
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* TypeScript-only extension. Iterate `(key, on, val)` members in branch `top`.
|
|
705
|
+
*
|
|
706
|
+
* This is the branch-scan form of `OnIoSet*`, still based on lexicographic
|
|
707
|
+
* physical key-prefix traversal.
|
|
708
|
+
*/
|
|
709
|
+
*getOnTopIoSetItemIter(db, top = new Uint8Array(0), sep = DOT_SEP) {
|
|
710
|
+
for (const [onkey, val] of this.getTopIoSetItemIter(db, top, sep)) {
|
|
711
|
+
const [key, on] = splitOnKey(onkey, sep);
|
|
712
|
+
yield [key, on, val];
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* TypeScript-only extension. Iterate `(key, on, val)` members for ordinals `>= on`.
|
|
717
|
+
*
|
|
718
|
+
* Empty `key` iterates the whole DB.
|
|
719
|
+
*/
|
|
720
|
+
*getOnAllIoSetItemIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
721
|
+
this.assertOpen();
|
|
722
|
+
if (!key.length) {
|
|
723
|
+
yield* this.getOnTopIoSetItemIter(db, new Uint8Array(0), sep);
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
const start = suffix(onKey(key, on, sep), 0, sep);
|
|
727
|
+
for (const entry of this.scan(db, { start })) {
|
|
728
|
+
const [onkey] = unsuffix(entry.key, sep);
|
|
729
|
+
const cval = entry.value;
|
|
730
|
+
const [ckey, con] = splitOnKey(onkey, sep);
|
|
731
|
+
if (!bytesEqual(ckey, key)) {
|
|
732
|
+
break;
|
|
733
|
+
}
|
|
734
|
+
yield [ckey, con, cval];
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* TypeScript-only extension. Iterate the last member for each ordinal bucket.
|
|
739
|
+
*
|
|
740
|
+
* Empty `key` iterates all logical keys and ordinals in the DB.
|
|
741
|
+
*/
|
|
742
|
+
*getOnAllIoSetLastItemIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
743
|
+
if (!key.length) {
|
|
744
|
+
for (const [onkey, val] of this.getIoSetLastItemIterAll(db, new Uint8Array(0), sep)) {
|
|
745
|
+
const [k, o] = splitOnKey(onkey, sep);
|
|
746
|
+
yield [k, o, val];
|
|
747
|
+
}
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
let last = null;
|
|
751
|
+
for (const [ckey, con, cval] of this.getOnAllIoSetItemIter(db, key, on, sep)) {
|
|
752
|
+
if (last === null) {
|
|
753
|
+
last = [ckey, con, cval];
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
if (con !== last[1]) {
|
|
757
|
+
yield last;
|
|
758
|
+
}
|
|
759
|
+
last = [ckey, con, cval];
|
|
760
|
+
}
|
|
761
|
+
if (last) {
|
|
762
|
+
yield last;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* TypeScript-only extension. Iterate backward over `(key, on, val)` members.
|
|
767
|
+
*
|
|
768
|
+
* Backward order is materialized from the forward iterator, then reversed.
|
|
769
|
+
*/
|
|
770
|
+
*getOnAllIoSetItemBackIter(db, key = new Uint8Array(0), on = null, sep = DOT_SEP) {
|
|
771
|
+
const items = key.length
|
|
772
|
+
? [...this.getOnAllIoSetItemIter(db, key, 0, sep)]
|
|
773
|
+
: [...this.getOnTopIoSetItemIter(db, new Uint8Array(0), sep)];
|
|
774
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
775
|
+
const item = items[i];
|
|
776
|
+
if (key.length && on !== null && item[1] > on) {
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
yield item;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* TypeScript-only extension. Iterate backward over the last member per ordinal bucket.
|
|
784
|
+
*/
|
|
785
|
+
*getOnAllIoSetLastItemBackIter(db, key = new Uint8Array(0), on = null, sep = DOT_SEP) {
|
|
786
|
+
const items = [...this.getOnAllIoSetLastItemIter(db, key, 0, sep)];
|
|
787
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
788
|
+
const item = items[i];
|
|
789
|
+
if (key.length && on !== null && item[1] > on) {
|
|
790
|
+
continue;
|
|
791
|
+
}
|
|
792
|
+
yield item;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
/*
|
|
796
|
+
* Insertion-ordered duplicate family (`IoDup*`)
|
|
797
|
+
* Logical shape: one physical key -> many native dupsort values.
|
|
798
|
+
* Multiplicity: native LMDB dupsort values.
|
|
799
|
+
* Ordering: hidden 33-byte value proem makes dupsort order equal insertion order.
|
|
800
|
+
* Parity status: direct KERIpy analogs with TS naming tweaks.
|
|
801
|
+
*
|
|
802
|
+
* Use this when dupsort size constraints are acceptable; use `IoSet*` when
|
|
803
|
+
* values may be too large for dupsort-backed storage.
|
|
804
|
+
*/
|
|
805
|
+
/**
|
|
806
|
+
* Add insertion-ordered duplicate values at `key`.
|
|
807
|
+
*
|
|
808
|
+
* Each stored value gets a hidden 33-byte proem (`32 hex chars + '.'`) so
|
|
809
|
+
* LMDB's lexicographic duplicate ordering becomes logical insertion order.
|
|
810
|
+
* Returned values later strip that proem away. Mirrors KERIpy `putIoDupVals`.
|
|
811
|
+
*/
|
|
812
|
+
putIoDupVals(db, key, vals) {
|
|
813
|
+
let result = false;
|
|
814
|
+
const existing = new Set(this.getIoDupVals(db, key).map((val) => bytesHex(val)));
|
|
815
|
+
let idx = 0;
|
|
816
|
+
const last = this.getValLast(db, key);
|
|
817
|
+
if (last) {
|
|
818
|
+
idx = parseIoDupOrdinal(last) + 1;
|
|
819
|
+
}
|
|
820
|
+
this.assertOpen();
|
|
821
|
+
this.transaction(() => {
|
|
822
|
+
for (const val of vals) {
|
|
823
|
+
const vh = bytesHex(val);
|
|
824
|
+
if (existing.has(vh)) {
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
this.putRow(db, key, withIoDupProem(idx, val));
|
|
828
|
+
idx += 1;
|
|
829
|
+
existing.add(vh);
|
|
830
|
+
result = true;
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
return result;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Add one insertion-ordered duplicate value at `key` if absent.
|
|
837
|
+
*
|
|
838
|
+
* Mirrors KERIpy `addIoDupVal`.
|
|
839
|
+
*/
|
|
840
|
+
addIoDupVal(db, key, val) {
|
|
841
|
+
const single = val === null ? [new Uint8Array(0)] : [val];
|
|
842
|
+
return this.putIoDupVals(db, key, single);
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Get insertion-ordered duplicate values at `key`, with the hidden proem removed.
|
|
846
|
+
*
|
|
847
|
+
* Ordering is logical insertion order because the hidden proem controls LMDB
|
|
848
|
+
* dupsort ordering. Mirrors KERIpy `getIoDupVals`.
|
|
849
|
+
*/
|
|
850
|
+
getIoDupVals(db, key) {
|
|
851
|
+
return this.getVals(db, key).map((val) => stripIoDupProem(val));
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Iterate insertion-ordered duplicate values at `key`, with the hidden proem removed.
|
|
855
|
+
*
|
|
856
|
+
* Mirrors KERIpy `getIoDupValsIter`.
|
|
857
|
+
*/
|
|
858
|
+
*getIoDupValsIter(db, key) {
|
|
859
|
+
for (const val of this.getValsIter(db, key)) {
|
|
860
|
+
yield stripIoDupProem(val);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Get the most recently inserted logical duplicate value at `key`.
|
|
865
|
+
*
|
|
866
|
+
* This uses the lexicographically last stored proem-prefixed duplicate and
|
|
867
|
+
* strips the hidden proem before returning. Mirrors KERIpy `getIoDupValLast`.
|
|
868
|
+
*/
|
|
869
|
+
getIoDupValLast(db, key) {
|
|
870
|
+
const last = this.getValLast(db, key);
|
|
871
|
+
return last ? stripIoDupProem(last) : null;
|
|
872
|
+
}
|
|
873
|
+
/** Delete all insertion-ordered duplicates at `key`. Mirrors KERIpy `delIoDupVals`. */
|
|
874
|
+
delIoDupVals(db, key) {
|
|
875
|
+
return this.delVals(db, key);
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Delete one insertion-ordered duplicate value at `key`, matching the stripped logical value.
|
|
879
|
+
*
|
|
880
|
+
* This performs a linear search over stored proem-prefixed duplicates. Mirrors
|
|
881
|
+
* KERIpy `delIoDupVal`.
|
|
882
|
+
*/
|
|
883
|
+
delIoDupVal(db, key, val) {
|
|
884
|
+
this.assertOpen();
|
|
885
|
+
for (const proVal of this.getVals(db, key)) {
|
|
886
|
+
if (bytesEqual(stripIoDupProem(proVal), val)) {
|
|
887
|
+
return this.removeRow(db, key, proVal);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
/** Count insertion-ordered duplicates at `key`. Mirrors KERIpy `cntIoDupVals`. */
|
|
893
|
+
cntIoDups(db, key) {
|
|
894
|
+
return this.cntVals(db, key);
|
|
895
|
+
}
|
|
896
|
+
/**
|
|
897
|
+
* Iterate `(key, val)` over branch `top`, stripping the hidden IoDup proem from each value.
|
|
898
|
+
*
|
|
899
|
+
* Mirrors KERIpy `getTopIoDupItemIter`.
|
|
900
|
+
*/
|
|
901
|
+
*getTopIoDupItemIter(db, top = new Uint8Array(0)) {
|
|
902
|
+
for (const [key, val] of this.getTopItemIter(db, top)) {
|
|
903
|
+
yield [key, stripIoDupProem(val)];
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
/*
|
|
907
|
+
* Ordinal insertion-ordered duplicate family (`OnIoDup*`)
|
|
908
|
+
* Logical shape: ordinal buckets, each bucket holding native dupsort duplicates.
|
|
909
|
+
* Multiplicity: native LMDB dupsort values within each exposed ordinal key.
|
|
910
|
+
* Ordering: exposed fixed-width ordinal in the key, hidden 33-byte proem in each duplicate value.
|
|
911
|
+
* Parity status: direct KERIpy analogs plus a few TS-only convenience methods.
|
|
912
|
+
*/
|
|
913
|
+
/**
|
|
914
|
+
* TypeScript-only convenience adding insertion-ordered duplicates at one exact ordinal key.
|
|
915
|
+
*
|
|
916
|
+
* This is the ordinal-bucketed counterpart to `putIoDupVals`. KERIpy exposes
|
|
917
|
+
* `addOnIoDupVal` and iterator-based accessors instead of this bulk helper.
|
|
918
|
+
*/
|
|
919
|
+
putOnIoDupVals(db, key, on = 0, vals, sep = DOT_SEP) {
|
|
920
|
+
return this.putIoDupVals(db, onKey(key, on, sep), vals);
|
|
921
|
+
}
|
|
922
|
+
/** Add one insertion-ordered duplicate at ordinal effective key. Mirrors KERIpy `addOnIoDupVal`. */
|
|
923
|
+
addOnIoDupVal(db, key, on = 0, val = null, sep = DOT_SEP) {
|
|
924
|
+
return this.addIoDupVal(db, onKey(key, on, sep), val);
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Append one insertion-ordered duplicate value at the next ordinal bucket for `key`.
|
|
928
|
+
*
|
|
929
|
+
* Mirrors KERIpy `appendOnIoDupVal`.
|
|
930
|
+
*/
|
|
931
|
+
appendOnIoDupVal(db, key, val, sep = DOT_SEP) {
|
|
932
|
+
return this.appendOnVal(db, key, withIoDupProem(0, val), sep);
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* TypeScript-only convenience returning all logical duplicates at one exact ordinal.
|
|
936
|
+
*
|
|
937
|
+
* KERIpy exposes scan-style iterators across ordinals rather than this exact
|
|
938
|
+
* per-ordinal list helper.
|
|
939
|
+
*/
|
|
940
|
+
getOnIoDupVals(db, key, on = 0, sep = DOT_SEP) {
|
|
941
|
+
if (!key.length) {
|
|
942
|
+
return [];
|
|
943
|
+
}
|
|
944
|
+
return this.getIoDupVals(db, onKey(key, on, sep));
|
|
945
|
+
}
|
|
946
|
+
/**
|
|
947
|
+
* TypeScript-only convenience iterating logical duplicates at one exact ordinal.
|
|
948
|
+
*
|
|
949
|
+
* No direct KERIpy equivalent: KERIpy `getOnIoDupValIter` scans all ordinals
|
|
950
|
+
* from `on` onward, which maps to `getOnIoDupIterAll` here.
|
|
951
|
+
*/
|
|
952
|
+
*getOnIoDupValsIter(db, key, on = 0, sep = DOT_SEP) {
|
|
953
|
+
if (!key.length) {
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
yield* this.getIoDupValsIter(db, onKey(key, on, sep));
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* TypeScript-only convenience fetching the last logical duplicate at one exact ordinal.
|
|
960
|
+
*/
|
|
961
|
+
getOnIoDupLast(db, key, on = 0, sep = DOT_SEP) {
|
|
962
|
+
return this.getIoDupValLast(db, onKey(key, on, sep));
|
|
963
|
+
}
|
|
964
|
+
/** Iterate the last logical duplicate value per ordinal bucket. Mirrors KERIpy `getOnIoDupLastValIter`. */
|
|
965
|
+
*getOnIoDupLastValIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
966
|
+
for (const [_, __, val] of this.getOnIoDupLastItemIter(db, key, on, sep)) {
|
|
967
|
+
yield val;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
/** Iterate `(key, on, val)` where `val` is the last logical duplicate per ordinal bucket. Mirrors KERIpy `getOnIoDupLastItemIter`. */
|
|
971
|
+
*getOnIoDupLastItemIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
972
|
+
this.assertOpen();
|
|
973
|
+
const start = key.length ? onKey(key, on, sep) : new Uint8Array(0);
|
|
974
|
+
let lonkey = null;
|
|
975
|
+
let lkey = null;
|
|
976
|
+
let lon = 0;
|
|
977
|
+
let last = null;
|
|
978
|
+
for (const entry of this.scan(db, { start })) {
|
|
979
|
+
const onkeyBytes = entry.key;
|
|
980
|
+
const cval = entry.value;
|
|
981
|
+
const [ckey, con] = splitOnKey(onkeyBytes, sep);
|
|
982
|
+
if (key.length && !bytesEqual(ckey, key)) {
|
|
983
|
+
break;
|
|
984
|
+
}
|
|
985
|
+
if (lonkey === null || !bytesEqual(lonkey, onkeyBytes)) {
|
|
986
|
+
if (lonkey !== null && lkey && last) {
|
|
987
|
+
yield [lkey, lon, stripIoDupProem(last)];
|
|
988
|
+
}
|
|
989
|
+
lonkey = new Uint8Array(onkeyBytes);
|
|
990
|
+
lkey = ckey;
|
|
991
|
+
lon = con;
|
|
992
|
+
}
|
|
993
|
+
last = cval;
|
|
994
|
+
}
|
|
995
|
+
if (lonkey !== null && lkey && last) {
|
|
996
|
+
yield [lkey, lon, stripIoDupProem(last)];
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Iterate `(key, on, val)` logical duplicates across a top branch.
|
|
1001
|
+
*
|
|
1002
|
+
* This mirrors the KERIpy helper added for normalized `OnIoDupSuber`
|
|
1003
|
+
* branch iteration and strips the hidden insertion-order proem from each
|
|
1004
|
+
* duplicate value before yielding it.
|
|
1005
|
+
*/
|
|
1006
|
+
*getOnTopIoDupItemIter(db, top = new Uint8Array(0), sep = DOT_SEP) {
|
|
1007
|
+
for (const [key, on, val] of this.getOnTopItemIter(db, top, sep)) {
|
|
1008
|
+
yield [key, on, stripIoDupProem(val)];
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
/** Delete all insertion-ordered duplicates at one ordinal effective key. TypeScript-local rename of KERIpy `delOnIoDupVals`. */
|
|
1012
|
+
delOnIoDups(db, key, on = 0, sep = DOT_SEP) {
|
|
1013
|
+
return this.delIoDupVals(db, onKey(key, on, sep));
|
|
1014
|
+
}
|
|
1015
|
+
/** Delete one insertion-ordered duplicate at one ordinal effective key. Mirrors KERIpy `delOnIoDupVal`. */
|
|
1016
|
+
delOnIoDupVal(db, key, on = 0, val = new Uint8Array(0), sep = DOT_SEP) {
|
|
1017
|
+
return this.delIoDupVal(db, onKey(key, on, sep), val);
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* TypeScript-only convenience counting logical duplicates at one exact ordinal.
|
|
1021
|
+
*
|
|
1022
|
+
* KERIpy does not expose this exact count helper on `LMDBer`.
|
|
1023
|
+
*/
|
|
1024
|
+
cntOnIoDups(db, key, on = 0, sep = DOT_SEP) {
|
|
1025
|
+
return this.cntIoDups(db, onKey(key, on, sep));
|
|
1026
|
+
}
|
|
1027
|
+
/** Iterate backwards over logical duplicate values. Mirrors KERIpy `getOnIoDupValBackIter`. */
|
|
1028
|
+
*getOnIoDupValBackIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
1029
|
+
for (const [_, __, val] of this.getOnIoDupItemBackIter(db, key, on, sep)) {
|
|
1030
|
+
yield val;
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
/** Iterate backwards over `(key, on, val)` logical duplicates. Mirrors KERIpy `getOnIoDupItemBackIter`. */
|
|
1034
|
+
*getOnIoDupItemBackIter(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
1035
|
+
const items = key.length
|
|
1036
|
+
? [...this.getOnIoDupItemIterAll(db, key, 0, sep)].filter((item) => item[1] <= on)
|
|
1037
|
+
: [...this.getOnIoDupItemIterAll(db, new Uint8Array(0), 0, sep)];
|
|
1038
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
1039
|
+
yield items[i];
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Iterate logical duplicate values for ordinals `>= on`.
|
|
1044
|
+
*
|
|
1045
|
+
* TypeScript-local name for KERIpy `getOnIoDupValIter`.
|
|
1046
|
+
*/
|
|
1047
|
+
*getOnIoDupIterAll(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
1048
|
+
for (const [_, __, val] of this.getOnIoDupItemIterAll(db, key, on, sep)) {
|
|
1049
|
+
yield val;
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Iterate `(key, on, val)` logical duplicates for ordinals `>= on`.
|
|
1054
|
+
*
|
|
1055
|
+
* TypeScript-local name for KERIpy `getOnIoDupItemIter`.
|
|
1056
|
+
*/
|
|
1057
|
+
*getOnIoDupItemIterAll(db, key = new Uint8Array(0), on = 0, sep = DOT_SEP) {
|
|
1058
|
+
for (const [ckey, con, cval] of this.getOnAllItemIter(db, key, on, sep)) {
|
|
1059
|
+
yield [ckey, con, stripIoDupProem(cval)];
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|