@ibgib/space-gib 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/Dockerfile +14 -0
- package/IMPLEMENTATION.md +484 -0
- package/README.md +46 -0
- package/dist/client/bootstrap.mjs +58 -0
- package/dist/client/bootstrap.mjs.map +7 -0
- package/dist/client/chunk-CT47Z5WU.mjs +21 -0
- package/dist/client/chunk-CT47Z5WU.mjs.map +7 -0
- package/dist/client/chunk-RHEDTRKF.mjs +235 -0
- package/dist/client/chunk-RHEDTRKF.mjs.map +7 -0
- package/dist/client/index.html +147 -0
- package/dist/client/index.mjs +2 -0
- package/dist/client/index.mjs.map +7 -0
- package/dist/client/script.mjs +2 -0
- package/dist/client/script.mjs.map +7 -0
- package/dist/client/style.css +605 -0
- package/dist/respec-gib.node.mjs +5 -0
- package/dist/server/server.mjs +20157 -0
- package/dist/server/server.mjs.map +7 -0
- package/generate-version-file.js +35 -0
- package/package.json +27 -0
- package/src/client/AUTO-GENERATED-version.mts +11 -0
- package/src/client/README.md +19 -0
- package/src/client/api/function-infos.web.mts +38 -0
- package/src/client/api/space-gib-api-bridge.mts +85 -0
- package/src/client/bootstrap.mts +49 -0
- package/src/client/components/keystone-creator/keystone-creator.css +139 -0
- package/src/client/components/keystone-creator/keystone-creator.html +26 -0
- package/src/client/components/keystone-creator/keystone-creator.mts +229 -0
- package/src/client/constants.mts +76 -0
- package/src/client/custom.d.ts +11 -0
- package/src/client/dev-tools.mts +540 -0
- package/src/client/helpers.web.mts +178 -0
- package/src/client/index.html +147 -0
- package/src/client/index.mts +59 -0
- package/src/client/script.mts +13 -0
- package/src/client/style.css +605 -0
- package/src/client/types.mts +85 -0
- package/src/client/ui/shell/space-gib-shell-constants.mts +24 -0
- package/src/client/ui/shell/space-gib-shell-service.mts +233 -0
- package/src/client/ui/shell/space-gib-shell-types.mts +5 -0
- package/src/client/witness/app/space-gib/space-gib-app-v1.mts +160 -0
- package/src/client/witness/app/space-gib/space-gib-constants.mts +38 -0
- package/src/client/witness/app/space-gib/space-gib-helper.mts +72 -0
- package/src/client/witness/app/space-gib/space-gib-types.mts +47 -0
- package/src/common/keystone-policies.mts +159 -0
- package/src/respec-gib.node.mts +6 -0
- package/src/server/README.md +18 -0
- package/src/server/bootstrap-helper.mts +141 -0
- package/src/server/bootstrap-helper.respec.mts +100 -0
- package/src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts +85 -0
- package/src/server/path-constants.mts +89 -0
- package/src/server/path-helper.mts +101 -0
- package/src/server/path-helper.respec.mts +94 -0
- package/src/server/serve-gib/CHANGELOG.md +29 -0
- package/src/server/serve-gib/README.md +34 -0
- package/src/server/serve-gib/constants.mts +1 -0
- package/src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts +104 -0
- package/src/server/serve-gib/handlers/api/health.handler.mts +23 -0
- package/src/server/serve-gib/handlers/api/health.respec.mts +51 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts +49 -0
- package/src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts +176 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts +261 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts +146 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts +198 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-get.respec.mts +107 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts +29 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts +70 -0
- package/src/server/serve-gib/handlers/api/keystone/keystone-post.respec.mts +130 -0
- package/src/server/serve-gib/handlers/error-handler.mts +36 -0
- package/src/server/serve-gib/handlers/handler-base.mts +383 -0
- package/src/server/serve-gib/handlers/static-handler.mts +82 -0
- package/src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts +498 -0
- package/src/server/serve-gib/handlers/ws/ws-helper.mts +111 -0
- package/src/server/serve-gib/handlers/ws/ws-types.mts +53 -0
- package/src/server/serve-gib/serve-gib-helpers.mts +32 -0
- package/src/server/serve-gib/serve-gib-v1.mts +172 -0
- package/src/server/serve-gib/serve-gib.respec.mts +90 -0
- package/src/server/serve-gib/types.mts +102 -0
- package/src/server/server-constants.mts +2 -0
- package/src/server/server.mts +96 -0
- package/tsconfig.json +29 -0
- package/tsconfig.server.json +29 -0
- package/tsconfig.test.json +27 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/server/server.mts", "../../../../libs/helper-gib/src/constants.mts", "../../../../libs/helper-gib/src/helpers/utils-helper.mts", "../../src/server/serve-gib/constants.mts", "../../src/server/serve-gib/serve-gib-v1.mts", "../../../../libs/ts-gib/src/helper.mts", "../../../../libs/ts-gib/src/V1/sha256v1.mts", "../../../../libs/ts-gib/src/V1/constants.mts", "../../../../libs/ts-gib/src/V1/transforms/transform-helper.mts", "../../src/server/bootstrap-helper.mts", "../../../../libs/node-gib/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.mts", "../../../../libs/ts-gib/src/V1/types.mts", "../../../../libs/ts-gib/src/V1/transforms/fork.mts", "../../../../libs/ts-gib/src/V1/transforms/mut8.mts", "../../../../libs/ts-gib/src/V1/transforms/rel8.mts", "../../../../libs/ts-gib/src/V1/v1-helper.mts", "../../../../libs/ts-gib/src/V1/validate-helper.mts", "../../../../libs/ts-gib/src/V1/factory.mts", "../../../../libs/core-gib/src/core-constants.mts", "../../../../libs/core-gib/src/common/other/other-types.mts", "../../../../libs/core-gib/src/witness/robbot/robbot-constants.mts", "../../../../libs/core-gib/src/witness/space/space-constants.mts", "../../../../libs/core-gib/src/common/root/root-constants.mts", "../../../../libs/core-gib/src/common/tag/tag-constants.mts", "../../../../libs/core-gib/src/common/other/other-constants.mts", "../../../../libs/core-gib/src/common/other/ibgib-constants.mts", "../../../../libs/core-gib/src/witness/app/app-constants.mts", "../../../../libs/core-gib/src/witness/space/bootstrap/bootstrap-constants.mts", "../../../../libs/encrypt-gib/src/types.mts", "../../../../libs/encrypt-gib/src/helper.mts", "../../../../libs/encrypt-gib/src/constants.mts", "../../../../libs/encrypt-gib/src/common/encrypt-decrypt-common.mts", "../../../../libs/encrypt-gib/src/stream-mode/encrypt-from-hex-stream-mode.mts", "../../../../libs/encrypt-gib/src/stream-mode/decrypt-to-hex-stream-mode.mts", "../../../../libs/encrypt-gib/src/stream-mode/decrypt-stream-mode.mts", "../../../../libs/encrypt-gib/src/stream-mode/encrypt-stream-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/encrypt-from-hex-block-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/decrypt-to-hex-block-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/decrypt-block-mode.mts", "../../../../libs/encrypt-gib/src/block-mode/encrypt-block-mode.mts", "../../../../libs/encrypt-gib/src/encrypt-decrypt.mts", "../../../../libs/core-gib/src/common/encrypt/encrypt-constants.mts", "../../../../libs/core-gib/src/witness/space/space-types.mts", "../../../../libs/core-gib/src/common/form/form-helper.mts", "../../../../libs/core-gib/src/witness/witness-form-builder.mts", "../../../../libs/core-gib/src/witness/app/app-helper.mts", "../../../../libs/core-gib/src/witness/app/chat-app/chat-app-types.mts", "../../../../libs/core-gib/src/witness/app/raw-app/raw-app-types.mts", "../../../../libs/core-gib/src/witness/app/todo-app/todo-app-types.mts", "../../../../libs/core-gib/src/witness/space/bootstrap/bootstrap-helper.mts", "../../../../libs/core-gib/src/common/meta-stone/meta-stone-constants.mts", "../../../../libs/core-gib/src/common/meta-stone/meta-stone-helper.mts", "../../../../libs/core-gib/src/witness/witness-constants.mts", "../../../../libs/core-gib/src/witness/space/space-helper.mts", "../../../../libs/core-gib/src/common/other/ibgib-helper.mts", "../../../../libs/node-gib/src/constants.mts", "../../../../libs/node-gib/src/witness/space/node-filesystem-space/node-filesystem-space-v1.mts", "../../../../libs/core-gib/src/witness/space/filesystem-space/filesystem-constants.mts", "../../../../libs/core-gib/src/witness/witness-base-v1.mts", "../../../../libs/core-gib/src/common/other/graph-helper.mts", "../../../../libs/core-gib/src/witness/witness-helper.mts", "../../../../libs/core-gib/src/witness/space/space-base-v1.mts", "../../../../libs/core-gib/src/witness/space/filesystem-space/filesystem-space-v1.mts", "../../../../libs/node-gib/src/witness/space/node-filesystem-space/node-filesystem-space-helper.mts", "../../../../libs/node-gib/src/witness/space/node-filesystem-space/node-filesystem-space-types.mts", "../../../../libs/node-gib/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-constants.mts", "../../../../libs/node-gib/src/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.mts", "../../src/server/server-constants.mts", "../../../../libs/core-gib/src/witness/space/outer-space/outer-space-types.mts", "../../../../libs/core-gib/src/common/encrypt/encrypt-types.mts", "../../../../libs/helper-gib/src/helpers/ssml-helper.mts", "../../../../libs/helper-gib/src/helpers/lex-helper.mts", "../../../../libs/core-gib/src/witness/robbot/robbot-types.mts", "../../../../libs/core-gib/src/witness/robbot/robbot-helper.mts", "../../../../libs/core-gib/src/common/pubsub/subject/subject-constants.mts", "../../../../libs/core-gib/src/common/pubsub/observable/observable-constants.mts", "../../../../libs/core-gib/src/common/pubsub/observable/observable-types.mts", "../../../../libs/core-gib/src/common/pubsub/observer/observer-types.mts", "../../../../libs/core-gib/src/common/pubsub/subject/subject-types.mts", "../../../../libs/core-gib/src/common/error/error-constants.mts", "../../../../libs/core-gib/src/common/error/error-helper.mts", "../../../../libs/core-gib/src/witness/factory/witness-factory-base.mts", "../../../../libs/core-gib/src/witness/factory/dynamic-form-factory-base.mts", "../../../../libs/core-gib/src/witness/light-witness-base-v1.mts", "../../../../libs/core-gib/src/common/pubsub/subscription/subscription-constants.mts", "../../../../libs/core-gib/src/common/pubsub/subscription/subscription-types.mts", "../../../../libs/core-gib/src/common/pubsub/observable/observable-helper.mts", "../../../../libs/core-gib/src/common/pubsub/subscription/subscription-v1.mts", "../../../../libs/core-gib/src/common/pubsub/subscription/subscription-helper.mts", "../../../../libs/core-gib/src/common/pubsub/observable/observable-event/observable-event-constants.mts", "../../../../libs/core-gib/src/common/pubsub/observable/observable-event/observable-event-helper.mts", "../../../../libs/core-gib/src/common/pubsub/observable/observable-base-v1.mts", "../../../../libs/core-gib/src/common/pubsub/subject/subject-v1.mts", "../../../../libs/core-gib/src/common/pubsub/subject/subject-helper.mts", "../../../../libs/core-gib/src/witness/anonymous-fn/anonymous-fn-constants.mts", "../../../../libs/core-gib/src/witness/anonymous-fn/anonymous-fn-helper.mts", "../../../../libs/core-gib/src/witness/anonymous-fn/anonymous-fn-v1.mts", "../../../../libs/core-gib/src/common/pubsub/observer/observer-helper.mts", "../../../../libs/core-gib/src/common/secret/secret-constants.mts", "../../../../libs/core-gib/src/witness/space/outer-space/outer-space-helper.mts", "../../../../libs/core-gib/src/witness/space/metaspace/metaspace-base.mts", "../../src/server/metaspace-nodeindexedspace/metaspace-nodeindexedspace.mts", "../../src/server/serve-gib/handlers/handler-base.mts", "../../src/server/path-constants.mts", "../../src/server/serve-gib/handlers/api/health.handler.mts", "../../src/server/path-helper.mts", "../../src/server/serve-gib/handlers/api/ibgib/ibgib-handler-types.mts", "../../src/server/serve-gib/serve-gib-helpers.mts", "../../src/server/serve-gib/handlers/api/ibgib/ibgib.handler.mts", "../../src/server/serve-gib/handlers/api/keystone/keystone-post.handler.mts", "../../../../libs/core-gib/src/keystone/keystone-types.mts", "../../../../libs/core-gib/src/keystone/keystone-constants.mts", "../../../../libs/core-gib/src/keystone/strategy/keystone-strategy.mts", "../../../../libs/core-gib/src/keystone/kdf/kdf-constants.mts", "../../../../libs/core-gib/src/keystone/kdf/kdf-helpers.mts", "../../../../libs/core-gib/src/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mts", "../../../../libs/core-gib/src/keystone/strategy/keystone-strategy-factory.mts", "../../../../libs/core-gib/src/keystone/keystone-helpers.mts", "../../src/server/serve-gib/handlers/api/keystone/keystone-handler-types.mts", "../../src/server/serve-gib/handlers/api/keystone/keystone-get.handler.mts", "../../src/server/serve-gib/handlers/api/keystone/keystone-genesis.handler.mts", "../../../../libs/core-gib/src/keystone/keystone-service-v1.mts", "../../src/server/serve-gib/handlers/api/keystone/keystone-evolve.handler.mts", "../../src/server/serve-gib/handlers/static-handler.mts", "../../src/server/serve-gib/handlers/error-handler.mts", "../../src/server/serve-gib/handlers/ws/ws-helper.mts", "../../src/server/serve-gib/handlers/api/debug/ws-echo.handler.mts", "../../src/common/keystone-policies.mts", "../../src/server/serve-gib/handlers/ws/sync-upgrade.handler.mts"],
|
|
4
|
+
"sourcesContent": ["/**\n * @module server\n *\n * Native Node.js HTTP server for space-gib \u2014 using the serve-gib microframework.\n */\n\nimport { createServer } from 'node:http';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { ServeGib_V1 } from './serve-gib/serve-gib-v1.mjs';\nimport { HealthHandler } from './serve-gib/handlers/api/health.handler.mjs';\nimport { IbGibHandler } from './serve-gib/handlers/api/ibgib/ibgib.handler.mjs';\nimport { KeystonePostHandler } from './serve-gib/handlers/api/keystone/keystone-post.handler.mjs';\nimport { KeystoneGetHandler } from './serve-gib/handlers/api/keystone/keystone-get.handler.mjs';\nimport { KeystoneGenesisHandler } from './serve-gib/handlers/api/keystone/keystone-genesis.handler.mjs';\nimport { KeystoneEvolveHandler } from './serve-gib/handlers/api/keystone/keystone-evolve.handler.mjs';\nimport { StaticFileHandler } from './serve-gib/handlers/static-handler.mjs';\nimport { ErrorHandler } from './serve-gib/handlers/error-handler.mjs';\nimport { canHandleWsUpgrade, handleWsEchoUpgrade } from './serve-gib/handlers/api/debug/ws-echo.handler.mjs';\nimport { SyncUpgradeHandler } from './serve-gib/handlers/ws/sync-upgrade.handler.mjs';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n// ---------------------------------------------------------------------------\n// Config\n// ---------------------------------------------------------------------------\n\nconst PORT = parseInt(process.env.PORT ?? '3000', 10);\nconst DATA_DIR = process.env.DATA_DIR ?? join(__dirname, '../../.data/ibgib-space');\nconst CLIENT_DIR = join(__dirname, '../client');\n\n// ---------------------------------------------------------------------------\n// Main\n// ---------------------------------------------------------------------------\n\nasync function main(): Promise<void> {\n const lc = '[space-gib server]';\n try {\n console.log(`${lc} starting...`);\n\n console.log(`${lc} dataDir: ${DATA_DIR}`);\n\n const syncUpgradeHandler = new SyncUpgradeHandler();\n\n // Initialize serve-gib\n const serveGib = new ServeGib_V1({\n port: PORT,\n dataDir: DATA_DIR,\n handlers: [\n new HealthHandler(),\n new IbGibHandler(),\n new KeystoneGenesisHandler(),\n new KeystoneEvolveHandler(),\n new KeystonePostHandler(),\n new KeystoneGetHandler(),\n new StaticFileHandler(CLIENT_DIR),\n ],\n errorHandler: new ErrorHandler()\n });\n\n const server = createServer(async (req, res) => {\n await serveGib.handleRequest(req, res);\n });\n\n // WebSocket upgrade handling \u2014 separate from the HTTP request pipeline\n // since Node.js fires `upgrade` events independently of `request` events.\n server.on('upgrade', async (req, socket, head) => {\n const reqCtx = await serveGib.prepareContext(req);\n \n // Check sync upgrade handler first\n const isSync = await syncUpgradeHandler.handleUpgrade(reqCtx, socket as any, head);\n \n // Fallback to debug echo if not handled by sync\n if (!isSync && canHandleWsUpgrade(req)) {\n handleWsEchoUpgrade(req, socket as any, head);\n } else if (!isSync) {\n // Reject unrecognized upgrade requests\n socket.write('HTTP/1.1 404 Not Found\\r\\n\\r\\n');\n socket.destroy();\n }\n });\n\n server.listen(PORT, '0.0.0.0', () => {\n console.log(`${lc} listening on http://0.0.0.0:${PORT}`);\n });\n\n } catch (error) {\n console.error(`${lc} fatal: ${extractErrorMsg(error)}`);\n process.exit(1);\n }\n}\n\nmain();\n", "\n/**\n * @internal\n * Used internally for logging.\n */\nexport const HELPER_LOG_A_LOT = false;\n\nexport const DEFAULT_UUID = undefined;\nexport const UUID_REGEXP = /^[a-zA-Z0-9_\\-.]{1,256}$/;\n\n/**\n * regular expression for a classname.\n *\n * Used in witnesses atm.\n */\nexport const CLASSNAME_REGEXP = /^[a-zA-Z0-9_]{1,255}$/;\n\n/**\n * capture groups for expected (in various places). will return `null` if\n * does not have an id section like `(E: abcdef32chars)`.\n */\nexport const ERROR_MSG_WITH_ID_CAPTURE_GROUPS_REGEXP = /^(\\[.+\\])?\\s?(\\(UNEXPECTED\\)|\\(unexpected\\))?(.+)(\\([EIWeiw]: [a-fA-F\\d]{32}\\))(\\(UNEXPECTED\\)|\\(unexpected\\))?$/;\nexport const ERROR_MSG_LOCATION_ONLY_REGEXP = /^(\\[.+\\]).+$/;\n\n/**\n * RegExp for a hexadecimal string of length 32\n */\nexport const HEXADECIMAL_HASH_STRING_REGEXP_32 = /^[0-9a-fA-F]{32}$/;\n/**\n * RegExp for a hexadecimal string of length 64\n */\nexport const HEXADECIMAL_HASH_STRING_REGEXP_64 = /^[0-9a-fA-F]{64}$/;\n\n/**\n * When you have a comma-delimited list of word characters and maybe some specials.\n *\n * @see {@link COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP_DESCRIPTION}\n */\nexport const COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP = /^[\\w\\-]+(,?[\\w+\\-])*$/;\n/**\n * Human-readable description to {@link COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP}\n *\n * It is meant to be used with validation errors helper.\n *\n * **WARNING** obviously this can get out of sync.\n */\nexport const COMMA_DELIMITED_SIMPLE_STRINGS_REGEXP_DESCRIPTION = 'text must only be comma-delimited, no-spaces simple words like \"comment,link,pic,x,under_score,hyphens-ok-too\"';\n\n/**\n * When expressing ibgib data paths, this will be used as the delimiter\n * to indicate a sub-object.\n *\n * # notes\n *\n * This should be used with the understanding that having overly-complex data\n * maps is an indication that the ibgib may possibly be better designed as\n * multiple ibgibs linked via their rel8ns.\n *\n * That said, I think it will be common for grouping settings, especially\n * mapping from external sources (API, SDK, etc.).\n */\nexport const DEFAULT_DATA_PATH_DELIMITER = '/';\n\n/**\n * If a string has only non-alphanumerics, this may be returned when getting a safer substring.\n */\nexport const ONLY_HAS_NON_ALPHANUMERICS = '_nonalphanumerics_';\n", "import { DEFAULT_DATA_PATH_DELIMITER, HELPER_LOG_A_LOT, ONLY_HAS_NON_ALPHANUMERICS } from \"../constants.mjs\";\n\nconst logalot = HELPER_LOG_A_LOT || false;\n\nlet crypto: any = globalThis.crypto;\nlet { subtle } = crypto;\n\nexport type HashAlgorithm = 'SHA-256' | 'SHA-512';\nexport const HashAlgorithm: { [key: string]: HashAlgorithm } = {\n 'sha_256': 'SHA-256' as HashAlgorithm,\n 'sha_512': 'SHA-512' as HashAlgorithm,\n}\n\nexport function clone(obj: any) {\n return JSON.parse(JSON.stringify(obj));\n}\nexport function getTimestamp(date?: Date) {\n return (date ?? new Date()).toUTCString();\n}\n\n/**\n * Simple hash function.\n *\n * NOTE:\n * This is not used for ibGib.gib values (ATOW)\n * but rather as a helper function for generating random UUIDs.\n *\n * @param s string to hash\n * @param algorithm to use, currently only 'SHA-256'\n */\nexport async function hash({\n s,\n algorithm = 'SHA-256',\n}: {\n s: string,\n algorithm?: HashAlgorithm,\n}): Promise<string> {\n if (!s) { return ''; }\n\n try {\n const validAlgorithms = Object.values(HashAlgorithm);\n if (!validAlgorithms.includes(algorithm)) {\n throw new Error(`Only ${validAlgorithms} implemented (E: 73cb52cd4d7f70c3415fdf695ba6ba23)`);\n }\n const msgUint8 = new TextEncoder().encode(s);\n const buffer = await subtle.digest(algorithm, msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (error) {\n console.error(extractErrorMsg(error.message));\n throw error;\n // return ''; // why had I decided to return an empty string on error?\n }\n}\n\n/**\n * Simple func to generate UUID (sha-256 hash basically).\n *\n * @param seedSize size of seed for UUID generation\n */\nexport async function getUUID(seedSize = 64): Promise<string> {\n let uuid: string = '';\n if (seedSize < 32) { throw new Error(`Seed size must be at least 32`); }\n if (!globalThis.crypto) { throw new Error(`Cannot create UUID, as unknown crypto library version. If using node.js, v19+ is required. (E: c02cee3fd8a94f678d3f4ebe9dc49797)`); }\n\n const values = crypto.getRandomValues(new Uint8Array(16));\n uuid = await hash({ s: values.join('') });\n\n if (!uuid) { throw new Error(`Did not create UUID...hmm...`); }\n\n return uuid;\n}\n\n/**\n * Syntactic sugar for JSON.stringify(obj, null, 2);\n *\n * @param obj to pretty stringify\n */\nexport function pretty(obj: any): string {\n return JSON.stringify(obj, null, 2);\n}\n\n/**\n * Just delays given number of ms.\n *\n * @param ms milliseconds to delay\n */\nexport async function delay(ms: number): Promise<void> {\n return new Promise<void>(resolve => {\n setTimeout(() => {\n resolve();\n }, ms);\n });\n}\n\n/**\n * extracts the error message from an error object/string/falsy arg.\n *\n * ## notes\n *\n * * some libs throw errors, some throw just strings.\n * * who knows what else it could be.\n *\n * ## todo\n *\n * * extract inner errors/causes if we ever use this function extensively.\n *\n * @param error the error object in the catch area of the try..catch block.\n * @returns error.message if it's a string, error itself if it's a string, or canned error messages if it's falsy or none of the above.\n */\nexport function extractErrorMsg(error: any): string {\n if (!error && error !== 0) {\n return '[error is falsy]';\n } else if (typeof error === 'string') {\n return error;\n } else if (typeof error.message === 'string') {\n return error.message;\n } else if (typeof error === 'number') {\n return JSON.stringify(error);\n } else if (!!error.error) {\n // the caller has used the \"wrong\" signature type\n console.warn(`[${extractErrorMsg.name}] this fn takes the raw error object. no destructure required. change your call from extractErrorMsg({error}) to extractErrorMsg(error). (W: ea49af5fd76d4b80a55a108d73a3e9b4)`);\n return extractErrorMsg(error.error);\n } else {\n return `[error is not a string and error.message is not a string. typeof error: ${typeof error} (E: d5a7723ca59646838308bc9e53a43134)]`;\n }\n}\n\nexport function groupBy<TItem>({\n items,\n keyFn,\n}: {\n items: TItem[],\n keyFn: (x: TItem) => string,\n}): { [key: string]: TItem[] } {\n const lc = `[${groupBy.name}]`;\n try {\n const result: { [key: string]: TItem[] } = {};\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const key = keyFn(item);\n result[key] = [...(result[key] ?? []), item];\n }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n\n/**\n * Just trying to centralize and standardize regular expressions here...\n */\nexport function getRegExp({\n min,\n max,\n chars,\n noSpaces,\n}: {\n min?: number,\n max?: number,\n chars?: string,\n noSpaces?: boolean,\n}): RegExp {\n min = min ?? 1;\n max = max ?? 999999999999;\n chars = chars ?? '';\n\n return noSpaces ?\n new RegExp(`^[\\\\w${chars}]{${min},${max}}$`) :\n new RegExp(`^[\\\\w\\\\s${chars}]{${min},${max}}$`);\n}\n\n/**\n * syntactic sugar for `(new Date()).getTime().toString()`\n * @returns ticks string\n */\nexport function getTimestampInTicks(timestamp?: string): string {\n let date: Date;\n if (timestamp) {\n date = new Date(timestamp);\n if (date.toString() === \"Invalid Date\") {\n throw new Error(`invalid date created by timestamp (${timestamp}) (E: cbd6aeefe00708184e276ea3c2532b22)`);\n }\n } else {\n date = new Date();\n }\n return date.getTime().toString();\n}\n\n/**\n * ## requires\n * at least either `startDate` or one of the intervals to be truthy.\n *\n * ## thanks\n *\n * https://stackoverflow.com/questions/8609261/how-to-determine-one-year-from-now-in-javascript\n *\n * ## tested manually eek\n```\nconsole.log(new Date().toUTCString());\n// Mon, 14 Feb 2022 14:19:32 GMT\nconsole.log(getExpirationUTCString({years: 1}));\n// Tue, 14 Feb 2023 14:19:32 GMT\nconsole.log(getExpirationUTCString({months: 13}));\n// Tue, 14 Mar 2023 13:19:32 GMT\nconsole.log(getExpirationUTCString({days: 365}));\n// Tue, 14 Feb 2023 14:19:32 GMT\nconsole.log(getExpirationUTCString({days: 45}));\n// Thu, 31 Mar 2022 13:19:32 GMT\nconsole.log(getExpirationUTCString({years: 1, days: 45, hours: 25, seconds: 70}));\n// Sat, 01 Apr 2023 14:20:42 GMT\nconsole.log(getExpirationUTCString({days: 10, hours: 10, seconds: 10}));\n// Fri, 25 Feb 2022 00:19:42 GMT\nconsole.log(getExpirationUTCString({years: 1, days: 45, hours: 25, seconds: 70}));\n// Sat, 01 Apr 2023 14:20:42 GMT\nconsole.log(getExpirationUTCString({years: 1, days: 45, hours: 25, seconds: 35}));\n// Sat, 01 Apr 2023 14:20:07 GMT\n```\n */\nexport function getExpirationUTCString({\n startDate,\n years,\n months,\n days,\n hours,\n seconds,\n}: {\n startDate?: Date,\n years?: number,\n months?: number,\n days?: number,\n hours?: number,\n seconds?: number,\n}): string {\n const lc = `[${getExpirationUTCString.name}]`;\n try {\n return addTimeToDate({\n startDate, years, months, days, hours, seconds,\n }).toUTCString();\n } catch (error) {\n console.log(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function addTimeToDate({\n startDate,\n years,\n months,\n days,\n hours,\n seconds,\n}: {\n startDate?: Date,\n years?: number,\n months?: number,\n days?: number,\n hours?: number,\n seconds?: number,\n}): Date {\n const lc = `[${addTimeToDate.name}]`;\n try {\n if (!startDate && !years && !months && !days && !hours && !seconds) {\n // throw here because otherwise we would return an expiration\n // timestamp string with now as the expiration, which doesn't make\n // sense.\n throw new Error(`either startDate or a time interval required. (E: 30248f8b306f443ab036fa8c313c50d8)`);\n }\n\n // don't want to mutate the incoming date\n startDate = startDate ?\n new Date(startDate) :\n new Date(); // default to now\n\n /** incoming years/months/days/hours/seconds to add to start date */\n let intervalToAdd: number;\n /** start date + interval in ticks, before assigning to Date obj */\n let newDateTicks: number;\n\n if (years) {\n intervalToAdd = startDate.getFullYear() + years;\n newDateTicks = startDate.setFullYear(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n months, days, hours, seconds, // all but years (just set)\n })\n } else if (months) {\n intervalToAdd = startDate.getMonth() + months;\n newDateTicks = startDate.setMonth(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, days, hours, seconds, // all but months (just set)\n })\n } else if (days) {\n intervalToAdd = startDate.getDate() + days;\n newDateTicks = startDate.setDate(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, months, hours, seconds, // all but days (just set)\n })\n } else if (hours) {\n intervalToAdd = startDate.getHours() + hours;\n newDateTicks = startDate.setHours(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, months, days, seconds, // all but hours (just set)\n })\n } else if (seconds) {\n intervalToAdd = startDate.getSeconds() + seconds;\n newDateTicks = startDate.setSeconds(intervalToAdd);\n // call recursively for other interval args (if any)\n return addTimeToDate({\n startDate: new Date(newDateTicks),\n years, months, days, hours, // all but seconds (just set)\n })\n } else {\n // we've called our function recursively and all intervals args\n // falsy now, so startDate is the output date.\n return startDate;\n }\n } catch (error) {\n console.log(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function isExpired({\n expirationTimestampUTC,\n}: {\n expirationTimestampUTC: string,\n}): boolean {\n const lc = `[${isExpired.name}]`;\n try {\n if (!expirationTimestampUTC) { throw new Error(`expirationTimestampUTC required (E: 5eeb1e29f93d64f70c71a8112080a222)`); }\n\n let expirationDate = new Date(expirationTimestampUTC);\n if (expirationDate.toUTCString() === \"Invalid Date\") { throw new Error(`invalid expirationTimestampUTC: ${expirationTimestampUTC} (E: 66a1a165bcf1f9336fe78856ab777822)`); }\n\n const now = new Date();\n const expired = expirationDate < now;\n return expired;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Creates a new array that is a unique set of incoming `arr`.\n * @param arr array to make unique\n * @returns new array with unique items\n */\nexport function unique<T>(arr: T[]): T[] {\n return Array.from(new Set<T>(arr));\n}\n\n// export function getExt(path: string): { filename: string, ext: string } {\n// const pathPieces = path.split('/');\n// const fullFilename = pathPieces[pathPieces.length-1];\n// if (fullFilename.includes('.') && !fullFilename.endsWith('.')) {\n// const lastDotIndex = fullFilename.lastIndexOf('.');\n// return {\n// filename: fullFilename.slice(0, lastDotIndex),\n// ext: fullFilename.slice(lastDotIndex+1),\n// };\n// } else {\n// return {filename: fullFilename, ext: \"\"}\n// }\n// }\n\nexport function patchObject({\n obj,\n value,\n path,\n pathDelimiter,\n logalot,\n}: {\n obj: Object,\n value: any,\n path: string,\n pathDelimiter?: string,\n logalot?: number | boolean,\n}): void {\n const lc = `[${patchObject.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!obj) { throw new Error(`obj required (E: 6a9dd32a361476e80b1bf7b91ec50522)`); }\n if (typeof obj !== 'object') { throw new Error(`obj must be type 'object' (E: 66fdc289b32c06492bd95f5d266e6a22)`); }\n if (!path) { throw new Error(`path required (at the very least should be the key in the root obj.) (E: fc779e7794ead8a0b44e5f2e776b0e22)`); }\n\n /** atow defaults to a forward slash, but could be a dot or who knows */\n pathDelimiter = pathDelimiter || DEFAULT_DATA_PATH_DELIMITER;\n\n /**\n * the target starts off at the object level itself, but we will\n * traverse the given path, updating the targetObj as we go.\n */\n let targetObj: { [key: string | number]: any } = obj;\n const pathPieces = path.split(pathDelimiter).filter(x => !!x);\n\n /** the last one is the key into the final targetObj with value */\n const key = pathPieces.pop()!;\n\n // ensure each intermediate path exists and is an object\n pathPieces.forEach(piece => {\n let currentValue = targetObj[piece];\n if (currentValue) {\n if (typeof currentValue !== 'object') { throw new Error(`invalid path into object. Each step along the path must be typeof === 'object', but typeof targetObj[\"${piece}\"] === ${typeof currentValue}. (value: ${currentValue}) (E: 38cf29c5f624a40b4b56502c2ec39d22)`); }\n } else {\n // if not exist, create it\n targetObj[piece] = {};\n }\n\n // update targetObj ref\n targetObj = targetObj[piece];\n });\n\n // reached target depth, so finally set the value\n targetObj[key] = value;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function getIdPool({\n n,\n}: {\n n: number,\n}): Promise<string[]> {\n const lc = `[${getIdPool.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n let result: string[] = [];\n for (let i = 0; i < n; i++) {\n const id = await getUUID();\n result.push(id.substring(0, 16));\n }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getSaferSubstring({\n text,\n length,\n keepLiterals = ['-'],\n replaceMap,\n}: {\n text: string;\n length?: number,\n /**\n * list of strings that you want to keep in the resultant string verbatim (without alteration).\n *\n * ## driving use case\n *\n * I want user comments that start with a question mark (?) to signify a\n * request to a robbot, e.g. \"?start someAddr^gib\" or whatever. So I want to\n * keep the question mark. I thought of an encoding mapping, like ? =>\n * \"__qstmark__\" but it's easier just to keep it, as this function was\n * originally intended to just nerf text in general because there was no\n * reason not to. well now there is a reason.\n *\n * I'm adding in a couple other characters in common use for whenever I get around\n * to making those mean something in the app (#, @)\n */\n keepLiterals?: string[],\n /**\n *\n */\n replaceMap?: { [s: string]: string },\n}): string {\n const lc = `[${getSaferSubstring.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 27437e312e5aa621adfebb84e059c822)`); }\n if (!text) { throw new Error(`text required (E: 87e0493613c8b30dfade83e1d2862a22)`); }\n\n let saferText: string = text;\n\n // before stripping \"unsafe\" characters, replace all instances of\n // keepLiterals with a temporary token if applicable\n let tokenToKeepMap: { [token: string]: string } = {};\n keepLiterals = keepLiterals ?? [];\n for (let i = 0; i < keepLiterals.length; i++) {\n const keep = keepLiterals[i];\n let tmpToken: string;\n do {\n tmpToken = pickRandom_Letters({ count: 10 });\n } while (tmpToken.includes(keep) || keep.includes(tmpToken) || text.includes(tmpToken));\n\n // replace instances of keep literals with our token\n if (saferText.includes(keep)) {\n tokenToKeepMap[tmpToken] = keep;\n while (saferText.includes(keep)) {\n saferText = saferText.replace(keep, tmpToken);\n }\n }\n }\n\n if (replaceMap && Object.keys(replaceMap).length > 0) {\n for (let i = 0; i < Object.keys(replaceMap).length; i++) {\n const toReplace = Object.keys(replaceMap)[i];\n const replaceWith = replaceMap[toReplace];\n while (saferText.includes(toReplace)) {\n saferText = saferText.replace(toReplace, replaceWith);\n }\n }\n }\n\n // now remove every non-alphanumeric\n saferText = saferText.replace(/\\W/g, '');\n\n // before checking length, put back in our keep literals (if any)\n const tokens = Object.keys(tokenToKeepMap);\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n while (saferText.includes(token)) {\n saferText = saferText.replace(token, tokenToKeepMap[token]);\n }\n }\n\n // trim the text to length if specified\n if (length && length > 0) {\n // debugger;\n // let resText: string;\n\n if (saferText.length > length) {\n if (logalot) { console.log(`${lc} curtailing length (I: d7a28e05daa5979c7686b4c1cf519b23)`); }\n saferText = saferText.substring(0, length);\n }\n }\n\n // replace if text only has characters/nonalphanumerics (\"unsafe\").\n if (saferText.length === 0) { saferText = ONLY_HAS_NON_ALPHANUMERICS; }\n\n return saferText;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * picks a random item from an array\n */\nexport function pickRandom<T extends any>({ x }: { x: T[] }): T | undefined {\n if ((x ?? []).length === 0) { return undefined; /* <<<< returns early */ }\n let randomIndex = Math.floor(Math.random() * x.length);\n return x[randomIndex];\n}\n\n/**\n * NOT strong crypto!\n *\n * returns `count` number of letters concatenated into a string.\n */\nexport function pickRandom_Letters({ count }: { count: number }): string {\n const lc = `${pickRandom_Letters.name}]`;\n try {\n if (!Number.isInteger(count)) { throw new Error(`count required to be a number. (E: c0a21d884ebd9afc4b2e8025207e0522)`); }\n let result: string = \"\";\n for (let i = 0; i < count; i++) {\n result += pickRandom({ x: 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.split(' ') });\n }\n if (result.length !== count) { throw new Error(`${lc} (UNEXPECTED) result.length !== count ? (E: 9bec4ec8f78610d8055e565415392a22)`); }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * creates a text selection of the entire element's text.\n *\n * ty https://stackoverflow.com/questions/985272/selecting-text-in-an-element-akin-to-highlighting-with-your-mouse\n *\n * @param el element whose text we're selecting\n */\nexport function selectElementText(el: HTMLElement): void {\n const lc = `[${selectElementText.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0971989c737e5b846894357f671ab322)`); }\n if (((document as any).body).createTextRange) {\n const range = ((document as any).body).createTextRange();\n range.moveToElementText(el);\n range.select();\n } else if (window.getSelection) {\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n const range = document.createRange();\n range.selectNodeContents(el);\n selection.addRange(range);\n } else {\n throw new Error(`(UNEXPECTED) window.getSelection() returned false? (E: 722b2d3084ed43fe8da22d889ddb52b8)`);\n }\n } else {\n throw new Error(`(UNEXPECTED) cannot select element text? (E: 163a1dd811b4f4bc22dd6823db859322)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * replaces an individual character at a position.\n *\n * ## driving use case\n *\n * part of functionality to replace entire words with underscores (_'s) for blanking out\n * stimulations in wordy robbot.\n *\n * @returns string with replaced characters\n */\nexport function replaceCharAt({\n s,\n pos,\n newChar,\n}: {\n s: string,\n pos: number,\n newChar: string,\n}): string {\n const chars = s.split('');\n chars[pos] = newChar;\n return chars.join('');\n}\n\n/**\n * Apparently it's a pain to determine if a keyboard event is hitting the\n * \"enter\" key across platforms.\n *\n * @link https://bugs.chromium.org/p/chromium/issues/detail?id=79407\n * @link https://stackoverflow.com/questions/3883543/javascript-different-keycodes-on-different-browsers\n *\n * @returns true if the event is the user pressing the \"Enter\" key, else false\n */\nexport function isKeyboardEvent_Enter(event: KeyboardEvent): boolean {\n const isEnter = event.key === 'Enter' || event.code === 'Enter';\n // event.keyCode === 10 || event.keyCode === 13 ||\n // event.charCode === 10 || event.charCode === 13;\n return isEnter;\n}\n\n/**\n * https://github.com/ionic-team/capacitor/issues/1564\n *\n * Still doesn't work...hmm\n */\nexport function getFileReaderHack(): FileReader {\n const lc = `[${getFileReaderHack.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d03faf53dd5f1cd1014f2f0e01058b22)`); }\n const fileReader = new FileReader();\n const zoneOriginalInstance = (fileReader as any)[\"__zone_symbol__originalInstance\"];\n return zoneOriginalInstance || fileReader;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * checks for mouse/trackball presence and infers keyboard when one is detected.\n *\n * ## aside\n *\n * It's amazing this isn't in an API...\n *\n * @returns true if by magical inference there is probably* a keyboard\n */\nexport function weHaveAPhysicalKeyboardProbably(): boolean {\n const lc = `${weHaveAPhysicalKeyboardProbably.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 70a952db8e1f23263ba98607def6f422)`); }\n const hasHover = window?.matchMedia?.('(hover:hover)').matches;\n const hasPointerFine = window?.matchMedia?.('(pointer:fine)').matches;\n return hasHover && hasPointerFine;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Check for either a physical keyboard or a relatively large window\n *\n * ## notes\n *\n * Such a long silly name because it's silly we don't have a better way of\n * detecting this with an official API.\n *\n * @returns true if we think that we're running on mobile\n */\nexport function weAreRunningOnMobileProbably(): boolean {\n const lc = `${weAreRunningOnMobileProbably.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5fd8deba6cb8cd40633c69371df95f22)`); }\n const keyboard = weHaveAPhysicalKeyboardProbably();\n const isMightyLargeForMobile = window.innerWidth > 810;\n return keyboard || isMightyLargeForMobile;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Combines two maps/arrays into a single one with some very basic, naive merge rules:\n *\n * 1. If a key exists in only one map, then it will be included in the output map.\n * 2. If a key exists in both maps and the type is array or map, then these will be recursively merged.\n * 3. If a key exists in both maps but is not an array or map, the dominant map's value wins.\n *\n * ## future\n *\n * In the future, if we want to keep these kinds of things around and be more\n * specific about mergers, we can always rel8 a merge strategy ibgib to be\n * referred to when performing merger.\n */\nexport function mergeMapsOrArrays_Naive<T extends {} | any[]>({\n dominant,\n recessive,\n}: {\n /**\n * when two keys are not arrays or maps themselves, this one's value is\n * chosen for output.\n */\n dominant: T,\n /**\n * when two keys are not arrays or maps themselves, this one's value is NOT\n * chosen for output.\n */\n recessive: T,\n}): T {\n const lc = `[${mergeMapsOrArrays_Naive.name}]`;\n try {\n if (Array.isArray(dominant) && Array.isArray(recessive)) {\n // arrays\n const output: any[] = clone(dominant) as any[];\n let warned = false;\n (recessive as []).forEach((recessiveItem: any) => {\n if (typeof (recessiveItem) === 'string') {\n if (!output.includes(recessiveItem)) { output.push(recessiveItem); }\n } else {\n if (!warned) {\n console.warn(`${lc} merging arrays of non-string elements. (W: d8ab113064834abc8eb5fe6c4cf87ba3)`);\n warned = true;\n }\n // we'll check the stringified version of recessive item against\n // the stringified dominant item.\n const xString = JSON.stringify(recessiveItem);\n if (!output.some(o => JSON.stringify(o) === xString)) {\n output.push(recessiveItem);\n }\n }\n });\n return (output as T);\n } else if (typeof (dominant) === 'object' && typeof (recessive) === 'object') {\n // maps\n const output: { [key: string]: any } = { ...recessive };\n const dominantKeys: string[] = Object.keys(dominant);\n const recessiveKeys: string[] = Object.keys(recessive);\n dominantKeys.forEach((key: string) => {\n if (recessiveKeys.includes(key)) {\n\n // naive merge for key that exists in both dominant & recessive\n if (Array.isArray((dominant as any)[key]) && Array.isArray((recessive as any)[key])) {\n // recursive call if both arrays\n output[key] = mergeMapsOrArrays_Naive<any[]>({\n dominant: (dominant as any)[key],\n recessive: (recessive as any)[key],\n });\n } else if (\n !!(dominant as any)[key] && !Array.isArray((dominant as any)[key]) && typeof ((dominant as any)[key]) === 'object' &&\n !!(recessive as any)[key] && !Array.isArray((recessive as any)[key]) && typeof ((recessive as any)[key]) === 'object'\n ) {\n // recursive call if both objects\n output[key] = mergeMapsOrArrays_Naive<{}>({\n dominant: (dominant as any)[key],\n recessive: (recessive as any)[key],\n });\n } else {\n (output as any)[key] = (dominant as any)[key];\n }\n } else {\n output[key] = (dominant as any)[key];\n }\n });\n\n return output as T;\n } else {\n // ? unknown matching of dominant and recessive\n console.warn(`${lc} unknown values or value types do not match. Both should either be an array or map. Dominant one wins categorically without any merging. (W: 3690ea19b81a4b89b98c1940637df62c)`);\n return (dominant as T);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n};\n", "export const GLOBAL_LOG_A_LOT = false;", "/**\n * @module serve-gib/serve-gib-v1\n *\n * The main entry point for processing incoming requests in the serve-gib\n * framework.\n */\n\nimport { IncomingMessage, ServerResponse } from 'node:http';\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from './constants.mjs';\nimport { RequestContext, ResponseResult, ServeGibHandler, ServeGibHttpMethod } from './types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport interface ServeGibOptions {\n /** Pipeline of handlers to check in order. */\n handlers: ServeGibHandler<any, any>[];\n /** Dedicated handler for errors (404, 500, etc.). */\n errorHandler: ServeGibHandler<any, any>;\n /** Port the server is listening on. */\n port: number;\n /**\n * Root data directory for the server. We will use this as the root dir for\n * all spaces that house multitenant ibgib data.\n */\n dataDir: string;\n}\n\nexport class ServeGib_V1 {\n private lc = `[${ServeGib_V1.name}]`;\n\n constructor(private options: ServeGibOptions) { }\n\n /**\n * Entry point for all incoming HTTP requests.\n */\n async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const lc = `${this.lc}[${this.handleRequest.name}]`;\n const start = Date.now();\n let reqCtx: RequestContext | undefined;\n\n try {\n // Contextualize the request\n reqCtx = await this.prepareContext(req);\n if (!reqCtx) { throw new Error(`(UNEXPECTED) reqCtx falsy? couldn't prepare context? (E: 401888c0f649dfdf0e2d21f86b3ff826)`); }\n\n // Execute pipeline\n let result: ResponseResult | undefined;\n for (const handler of this.options.handlers) {\n result = await handler.handleRoute(reqCtx);\n if (result) { break; }\n }\n\n // Fallback if no handler matched\n if (!result) {\n result = await this.options.errorHandler.handleRoute(reqCtx);\n }\n\n // Final output\n if (result) {\n this.sendResponse(res, result);\n } else {\n // If even the error handler didn't produce a result\n this.sendResponse(res, { status: 404, body: 'Not Found' });\n }\n\n } catch (error) {\n console.error(`${lc} Fatal error handling ${req.method} ${req.url}: ${extractErrorMsg(error)}`);\n try {\n // Try to use the error handler for the fatal error\n if (reqCtx) {\n const errorResult = await this.options.errorHandler.handleRoute(reqCtx);\n this.sendResponse(res, errorResult ?? { status: 500, body: 'Internal Server Error' });\n } else {\n throw new Error(`errored before reqCtx could be set. (E: d77ab84b4f8874e188cfa8e9895f1226)`);\n }\n } catch (innerError) {\n // Total collapse fallback\n console.error(`${lc} Collapse in error handler: ${extractErrorMsg(innerError)}`);\n res.writeHead(500);\n res.end('Critical Server Error');\n }\n } finally {\n const duration = Date.now() - start;\n // Standard access logging\n console.log(`${lc} ${req.method} ${req.url} -> ${res.statusCode} (${duration}ms)`);\n }\n }\n\n /**\n * Builds request context (e.g. extracting/decoding URL, path segments, body\n * content, etc.), and initializes the request's metaspace if applicable.\n */\n public async prepareContext(req: IncomingMessage): Promise<RequestContext> {\n const lc = `${this.lc}[${this.prepareContext.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ad9e9c678d0538c2d1e16ca8063d4426)`); }\n\n /**\n * These are NOT all of the validation we do on the context, rather,\n * it is just simple initial validation.\n */\n const initialValidationErrors: string[] = [];\n\n const rawUrl = req.url ?? '/';\n const protocol = (req.headers['x-forwarded-proto'] as string) || 'http'; // todo: who owns the req.headers? Can an attacker manipulate this?\n const url = new URL(rawUrl, `${protocol}://localhost:${this.options.port}`); // todo: wth?? Why are we hard-coding localhost? in the URL object?\n\n const pathname = url.pathname;\n const rawPathSegments = pathname.split('/');\n const decodedPathSegments = rawPathSegments.map(s => decodeURIComponent(s));\n\n const body = await this.readBody(req);\n\n const reqCtx: RequestContext = {\n rawUrl,\n pathname,\n method: req.method?.toUpperCase() as ServeGibHttpMethod ?? 'GET',\n protocol,\n body,\n rawPathSegments,\n decodedPathSegments,\n url,\n dataDir: this.options.dataDir,\n headers: req.headers,\n }\n\n return reqCtx;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /** Reads the full request body as UTF-8. */\n private readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n req.on('error', reject);\n });\n }\n\n /** Sends the response result to the client. */\n private sendResponse(res: ServerResponse, result: ResponseResult): void {\n const lc = `${this.lc}[${this.sendResponse.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 37369cf120c14780e8652bf27ada1726)`); }\n\n const { status, headers = {}, body, isJson = false } = result;\n\n let payload: any = body;\n if (isJson) {\n headers['Content-Type'] = 'application/json; charset=utf-8';\n payload = JSON.stringify(body);\n }\n\n res.writeHead(status, headers);\n res.end(payload);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "import { Ib, Gib, IbGib, IbGibAddr, IbAndGib } from './types.mjs';\n\n\n/**\n * Gets the ib^gib address from the given ib and gib or\n * from the ibGib object.\n *\n * Need to refactor to getIbGibAddr\n */\nexport function getIbGibAddr({\n ib, gib, ibGib, delimiter = '^'\n}: {\n ib?: Ib,\n gib?: Gib,\n ibGib?: IbGib,\n delimiter?: string\n}): IbGibAddr {\n ib = ib || ibGib?.ib || '';\n gib = gib || ibGib?.gib || '';\n return ib + delimiter + gib;\n}\n\n/**\n * Get the ib and gib fields from an ibGib object or ibGibAddr\n * with the given `delimiter`.\n */\nexport function getIbAndGib({\n ibGib,\n ibGibAddr,\n delimiter = '^'\n}: {\n ibGibAddr?: IbGibAddr,\n ibGib?: IbGib,\n delimiter?: string\n}): IbAndGib {\n const lc = '[getIbAndGib]';\n if (!ibGibAddr) {\n if (ibGib) {\n ibGibAddr = getIbGibAddr({ ibGib });\n } else {\n throw new Error(`${lc} We need either an address or an ibGib object`);\n }\n }\n if (!ibGibAddr) { throw new Error(`${lc} Couldn't get ibGibAddr. ibGib invalid?`); }\n\n if (!delimiter) { delimiter = '^'; }\n\n const pieces = ibGibAddr.split(delimiter);\n if (pieces.length === 2) {\n // normal v1 case, e.g. 'ib^gib' or 'tag home^ABC123'\n return { ib: pieces[0], gib: pieces[1] };\n } else if (pieces.length === 1 && ibGibAddr.endsWith(delimiter)) {\n // normal v1 primitive, e.g. '7^' or 'name^'\n return { ib: pieces[0], gib: '' };\n } else if (pieces.length === 1 && ibGibAddr.startsWith(delimiter)) {\n // only gib/hash is provided like maybe a binary file\n // e.g. ^ABC123 or ^XYZ456 or ^some_gib_that_isnt_a_hash\n return { ib: '', gib: pieces[0] };\n } else if (pieces.length === 2 && pieces[0] === '' && pieces[1] === '') {\n // edge case of address is only the delimiter.\n // So it's the primitive for that delimiter\n return { ib: delimiter, gib: '' };\n // } else if (pieces.length === 0 ) {\n // ibGibAddr is falsy, so would have thrown earlier in this function\n // I'm just noting this case for intent ATOW\n } else {\n console.warn(`${lc} multiple delimiters found in ibGibAddr. Considering last delimiter as the demarcation of gib hash`);\n // e.g. 'ib^ABC123^gib'\n // ib: 'ib^ABC123'\n // gib: 'gib'\n return {\n ib: pieces.slice(0, pieces.length - 1).join(delimiter),\n gib: pieces.slice(pieces.length - 1)[0],\n }\n }\n}\n\n\n/**\n * Normalizes an object/value for consistent hashing.\n * - Recursively processes objects and arrays.\n * - For objects:\n * - Sorts keys alphabetically.\n * - Removes properties whose values are `undefined`.\n * - Keeps properties whose values are `null`.\n * - For arrays:\n * - Preserves element order.\n * - Recursively normalizes each element.\n * - Primitives (strings, numbers, booleans) and `null` are returned as is.\n *\n * @param value The value to normalize.\n * @returns The normalized value.\n *\n * This has been adjusted due to conversation with Gemini and working on python\n * port. The main thing here is that we normalize array members, but not the\n * array itself. This way the array's order is preserved, but any object members\n * are themselves normalized.\n */\nexport function toNormalizedForHashing(value: any): any {\n // Handle null, primitives (string, number, boolean) directly.\n // `undefined` at the top level will be handled by the caller or become part of an object/array.\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Handle Arrays: recursively normalize elements, preserve order\n if (Array.isArray(value)) {\n return value.map(element => toNormalizedForHashing(element));\n }\n\n // Handle Objects (plain objects)\n const normalizedObject: { [key: string]: any } = {};\n const sortedKeys = Object.keys(value).sort();\n\n for (const key of sortedKeys) {\n const propertyValue = value[key];\n if (propertyValue !== undefined) { // CRITICAL: Only omit if value is undefined\n normalizedObject[key] = toNormalizedForHashing(propertyValue);\n }\n // If propertyValue is undefined, it's omitted from normalizedObject.\n // If propertyValue is null, it's included.\n }\n return normalizedObject;\n}\n", "import { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from \"./types.mjs\";\nimport { Ib } from \"../types.mjs\";\n\nlet crypto: any = globalThis.crypto;\nlet { subtle } = crypto;\n\n/**\n * Performs the gib hash like V1\n *\n * I have it all in one function for smallest, most independent version possible.\n *\n * #thanks https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest\n * #thanks https://stackoverflow.com/questions/49129643/how-do-i-merge-an-array-of-uint8arrays\n * #thanks https://stackoverflow.com/a/49129872/3897838 (answer to above)\n *\n * @param ibGib ibGib for which to calculate the gib\n */\nexport function sha256v1_old(ibGib: IbGib_V1, salt: string = \"\"): Promise<string> {\n // console.log('func_gib_sha256v1 executed');\n if (!salt) { salt = \"\"; }\n let hashToHex = async (message: string | undefined) => {\n if (!message) { return \"\"; }\n const msgUint8 = new TextEncoder().encode(message);\n const buffer = await subtle.digest('SHA-256', msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n // return hashAsHex\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n let hashToHex_Uint8Array = async (salt: string, msgUint8: Uint8Array) => {\n let tohashUint8Array: Uint8Array;\n if (salt) {\n const msgUint8_salt = new TextEncoder().encode(salt);\n tohashUint8Array = new Uint8Array(msgUint8_salt.length + msgUint8.length);\n tohashUint8Array.set(msgUint8_salt);\n tohashUint8Array.set(msgUint8, msgUint8_salt.length);\n } else {\n tohashUint8Array = msgUint8;\n }\n const hashAsBuffer = await subtle.digest('SHA-256', tohashUint8Array);\n const hashAsArray = Array.from(new Uint8Array(hashAsBuffer));\n // return hashAsHex\n return hashAsArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n let hashFields;\n if (salt) {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(salt + ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(salt + JSON.stringify(rel8ns))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n\n // change this for binaries (Uint8Array data)\n // const dataHash: string = hasData ? (await hashToHex(salt + JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array(salt, data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(salt + JSON.stringify(data))).toUpperCase();\n }\n }\n\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(salt + ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(salt + ibHash)).toUpperCase();\n return allHash;\n };\n } else {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n // const hasData = Object.keys((data) || {}).length > 0;\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(JSON.stringify(rel8ns))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n // const dataHash: string = hasData ? (await hashToHex(JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array('', data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(JSON.stringify(data))).toUpperCase();\n }\n }\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(ibHash)).toUpperCase();\n return allHash;\n }\n }\n return hashFields(ibGib.ib, ibGib?.data, ibGib?.rel8ns);\n}\n\nexport function sha256v1(ibGib: IbGib_V1, salt: string = \"\"): Promise<string> {\n // console.log('func_gib_sha256v1 executed');\n if (!salt) { salt = \"\"; }\n let hashToHex = async (message: string | undefined) => {\n if (!message) { return \"\"; }\n const msgUint8 = new TextEncoder().encode(message);\n const buffer = await subtle.digest('SHA-256', msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n // return hashAsHex\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n let hashToHex_Uint8Array = async (salt: string, msgUint8: Uint8Array) => {\n let tohashUint8Array: Uint8Array;\n if (salt) {\n const msgUint8_salt = new TextEncoder().encode(salt);\n tohashUint8Array = new Uint8Array(msgUint8_salt.length + msgUint8.length);\n tohashUint8Array.set(msgUint8_salt);\n tohashUint8Array.set(msgUint8, msgUint8_salt.length);\n } else {\n tohashUint8Array = msgUint8;\n }\n const hashAsBuffer = await subtle.digest('SHA-256', tohashUint8Array);\n const hashAsArray = Array.from(new Uint8Array(hashAsBuffer));\n // return hashAsHex\n return hashAsArray.map(b => b.toString(16).padStart(2, '0')).join('');\n };\n\n /**\n * THIS IS DUPLICATED CODE IN THE RESPEC FILE. ANY CHANGES HERE MUST\n * MANUALLY BE CHANGED IN THE RESPEC FILE!!!\n *\n * Normalizes an object/value for consistent hashing.\n * - Recursively processes objects and arrays.\n * - For objects:\n * - Sorts keys alphabetically.\n * - Removes properties whose values are `undefined`.\n * - Keeps properties whose values are `null`.\n * - For arrays:\n * - Preserves element order.\n * - Recursively normalizes each element.\n * - Primitives (strings, numbers, booleans) and `null` are returned as is.\n *\n * THIS IS DUPLICATED CODE IN THE RESPEC FILE. ANY CHANGES HERE MUST\n * MANUALLY BE CHANGED IN THE RESPEC FILE!!!\n *\n * @param value The value to normalize.\n * @returns The normalized value.\n */\n const toNormalizedForHashing = (value: any) => {\n // Handle null, primitives (string, number, boolean) directly.\n // `undefined` at the top level will be handled by the caller or become part of an object/array.\n if (value === null || typeof value !== 'object') {\n return value;\n }\n\n // Handle Arrays: recursively normalize elements, preserve order\n if (Array.isArray(value)) {\n return value.map(element => toNormalizedForHashing(element));\n }\n\n // Handle Objects (plain objects)\n const normalizedObject: { [key: string]: any } = {};\n const sortedKeys = Object.keys(value).sort();\n\n for (const key of sortedKeys) {\n const propertyValue = value[key];\n if (propertyValue !== undefined) { // CRITICAL: Only omit if value is undefined\n normalizedObject[key] = toNormalizedForHashing(propertyValue);\n }\n // If propertyValue is undefined, it's omitted from normalizedObject.\n // If propertyValue is null, it's included.\n }\n return normalizedObject;\n\n // if (!obj) {\n // return obj; /* <<<< returns early */\n // } else if (typeof obj === 'string' || Array.isArray(obj)) {\n // return obj.concat(); /* <<<< returns early */\n // } else if (typeof obj !== 'object') {\n // // Return non-objects as is, we don't know how to concat/copy it...hmm...\n // return obj; /* <<<< returns early */\n // }\n\n // // we have an object. we will create a new object and populate it.\n // const normalized = {};\n\n // // sort keys alphabetically\n // // NOTE: this does NOT mutate obj as Object.keys produces a new array\n // const keys = Object.keys(obj).sort();\n\n // for (const key of keys) {\n // const value = obj[key];\n // if (value !== undefined) {\n // // Recursively normalize if the value is an object\n // normalized[key] = (typeof value === 'object' && value !== null) ? toNormalizedForHashing(value) : value;\n // }\n // }\n // return normalized;\n }\n\n\n let hashFields;\n if (salt) {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(salt + ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(salt + JSON.stringify(toNormalizedForHashing(rel8ns)))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n\n // change this for binaries (Uint8Array data)\n // const dataHash: string = hasData ? (await hashToHex(salt + JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array(salt, data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(salt + JSON.stringify(toNormalizedForHashing(data)))).toUpperCase();\n }\n }\n\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(salt + ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(salt + ibHash)).toUpperCase();\n return allHash;\n };\n } else {\n hashFields = async (ib: Ib, data: IbGibData_V1 | undefined, rel8ns: IbGibRel8ns_V1 | undefined) => {\n const hasRel8ns =\n Object.keys(rel8ns || {}).length > 0 &&\n Object.keys(rel8ns || {}).some(k => rel8ns![k] && rel8ns![k]!.length > 0);\n // const hasData = Object.keys((data) || {}).length > 0;\n let hasData = !!data;\n if (hasData) {\n if (typeof data === 'string') {\n hasData = (data as string).length > 0;\n } else if (data instanceof Uint8Array) {\n hasData = true;\n } else if (typeof data === 'object') {\n hasData = Object.keys((data) || {}).length > 0;\n } else {\n hasData = true;\n }\n }\n const ibHash = (await hashToHex(ib)).toUpperCase();\n // empty, null, undefined all treated the same at this level.\n const rel8nsHash: string = hasRel8ns ? (await hashToHex(JSON.stringify(toNormalizedForHashing(rel8ns)))).toUpperCase() : \"\";\n // empty, null, undefined all treated the same at this level (though not farther down in data)\n // const dataHash: string = hasData ? (await hashToHex(JSON.stringify(data))).toUpperCase() : \"\";\n let dataHash: string = \"\";\n if (hasData) {\n if (data instanceof Uint8Array) {\n dataHash = (await hashToHex_Uint8Array('', data)).toUpperCase();\n } else {\n dataHash = (await hashToHex(JSON.stringify(toNormalizedForHashing(data)))).toUpperCase();\n }\n }\n // if the ibgib has no rel8ns or data, the hash should be just of the ib itself.\n const allHash = hasRel8ns || hasData ?\n (await hashToHex(ibHash + rel8nsHash + dataHash)).toUpperCase() :\n (await hashToHex(ibHash)).toUpperCase();\n return allHash;\n }\n }\n return hashFields(ibGib.ib, ibGib?.data, ibGib?.rel8ns); // conditional nav ibGib?.data and ibGib?.rel8ns\n}\n\n/**\n * I have one large-ish sha256 function for gibbing purposes\n * (dream where metabootstrapping is better)\n * this is just testing a function that is internal to the sha256v1 func.\n * terrible as can be duplicated, but simple for now.\n */\nexport async function hashToHexCopy(\n message: string | undefined\n): Promise<string | undefined> {\n if (!message) { return \"\"; }\n try {\n const msgUint8 = new TextEncoder().encode(message);\n const buffer = await subtle.digest('SHA-256', msgUint8);\n const asArray = Array.from(new Uint8Array(buffer));\n return asArray.map(b => b.toString(16).padStart(2, '0')).join('');\n } catch (e) {\n console.error(extractErrorMsg(e.message));\n return undefined;\n }\n};\n", "import { IbGib_V1 } from './types.mjs';\n\n/**\n * This is essentially an alias of the string literal `'ib'`\n */\nexport const IB = 'ib';\n/**\n * This is essentially an alias of the string literal `'gib'`\n *\n * When you have a primitive ibgib, this should be the `ibGib.gib` value, as\n * there is no hashing metadata for primitives.\n */\nexport const GIB = 'gib';\n/**\n * This is the root ibgib from which all ibgib are ultimately forked.\n * It has 0 and infinite data, 0 and infinite rel8ns. Its ib and gib\n * are simply 'ib' and 'gib'.\n */\nexport const ROOT: IbGib_V1 = { ib: IB, gib: GIB, }\n/**\n * The default delimiter is the caret (^) symbol. This is derived from\n * taking an ib^gib address and turning it into an ibGib object (note\n * the capitalized \"G\").\n */\nexport const IBGIB_DELIMITER = '^';\n/**\n * Gib is often just a single hash for a single ib^gib record.\n * But if the ibgib has a tjp, which implies a timeline (\"stream\"\n * in some senses), then we will include the tjp gib hash alongside the\n * individual punctilear ibgib frame.\n *\n * ATOW this has the default schema of\n *\n * @example \"comment abc^TJPHASH123\", \"comment abc^TJPHASH123.THISRECORDHASH456\"\n */\nexport const GIB_DELIMITER = '.';\n/**\n * This is the address of the ROOT ibgib with the default delimiter (caret ^).\n */\nexport const ROOT_ADDR = 'ib^gib'; // `${IB}${IBGIB_DELIMITER}${GIB}`;\n/**\n * Some rel8ns should not be able to be renamed or removed, as these have\n * \"special\" semantic meaning in the low-level graphing protocol.\n *\n * ## notes\n *\n * * Of course, this can be forged or tinkered with, and that ultimately is what\n * consensus would be utilized for.\n * * protocols built on top of this may also have reserved rel8n/data key names\n */\nexport const FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES = ['past', 'ancestor', 'dna', 'tjp'];\n\nexport const IB_MAX_LENGTH_DEFAULT = 155;\n\n/**\n * Defaults to word characters, space, tab, hyphen, and other\n * non-slash (path navigating) chars.\n *\n * Does not allow new lines or other whitespace, only tabs and spaces.\n *\n * ## atow\n *\n * `^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`\n */\nexport const IB_REGEXP_DEFAULT = new RegExp(`^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`);", "import { clone, extractErrorMsg, } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { TransformOpts, IbGib, Gib, IbGibAddr, } from \"../../types.mjs\";\nimport { getIbGibAddr, getIbAndGib, } from \"../../helper.mjs\";\nimport { sha256v1, } from \"../sha256v1.mjs\";\nimport { GibInfo, IbGib_V1, } from \"../types.mjs\";\nimport { IBGIB_DELIMITER, GIB, GIB_DELIMITER } from \"../constants.mjs\";\n\nexport async function buildDna<TSrc extends IbGib_V1, TOpts extends TransformOpts<TSrc>>(\n opts: TOpts,\n): Promise<IbGib_V1> {\n const transformData: TOpts = clone(opts);\n let lc = `[${buildDna.name}]`;\n\n // remove references to the srcAddr, as this will be captured\n // by the ibGib's `past` rel8n. This way, we can reapply dna\n // to different src's more easily, as well as have less unique dna\n if (transformData.srcAddr) { delete transformData.srcAddr; }\n\n // remove all references to actual objects in this, we just\n // want the data. ATOW, src is a reference to the src object\n // and we only want the srcAddr\n delete transformData.src;\n\n // dna is never timestamped or uniquely identified hmm...\n // or rel8d to anything...hmmm\n // so much dna, best to minimize though of course we dont\n // want to prematurely optimize...but there's a looooot of dna.\n // best to share/reuse as much as possible.\n const result: IbGib_V1 = {\n ib: transformData.type!,\n data: transformData,\n rel8ns: {\n ancestor: [\n `${transformData.type!.toString()}${IBGIB_DELIMITER}${GIB}` // e.g. fork^gib\n ]\n }\n };\n\n result.gib = await sha256v1(result);\n\n return result;\n}\n\nexport function isDna({ ibGib }: { ibGib: IbGib }): boolean {\n const lc = `[${isDna.name}]`;\n try {\n if (!ibGib) { throw new Error(`ibGib required.`); }\n\n // console.log(`${lc} ibGib: ${pretty(ibGib)}`);\n\n // ancestor is known transform is the best way for v1 ATOW\n const knownTransformPrimitiveAddrs =\n ['fork', 'mut8', 'rel8', 'plan'].map(x => `${x}^${GIB}`); // plan from prev versions\n const hasTransformAncestor =\n ((ibGib as any).rel8ns) &&\n ((ibGib as any).rel8ns.ancestor) &&\n (Array.isArray((ibGib as any).rel8ns.ancestor)) &&\n ((((ibGib as any).rel8ns.ancestor) as any) as any).\n some((x: any) => knownTransformPrimitiveAddrs.includes(x));\n\n return hasTransformAncestor || false;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport function isPrimitive({ ibGib, gib }: { ibGib?: IbGib_V1, gib?: Gib }): boolean {\n if (ibGib) {\n return isPrimitive({ gib: ibGib.gib });\n } else if (gib) {\n return gib === GIB;\n } else {\n // falsy gib means it's primitive or a programming error...hmm\n return true;\n }\n}\n\n/**\n * Generates the gib of a given `ibGib` depending on\n * @returns gib - either bare hash for those with no tjp; or tjp-scoped hash; or 'gib' for primitives\n */\nexport async function getGib({\n ibGib,\n hasTjp,\n tjpAddr,\n gibDelimiter,\n isPrimitive,\n hashAlgorithm,\n}: {\n /**\n * We'll take the `ib`, `data`, and `rel8ns` from this\n */\n ibGib: IbGib_V1,\n /**\n * If true, then we'll treat this as having a tjp.\n * If falsy, then we'll check the internals of the ibGib to see if it has a tjp.\n */\n hasTjp?: boolean;\n /**\n * @deprecated\n *\n * IGNORED\n *\n * This is now always searched for in the ibGib itself.\n */\n tjpAddr?: IbGibAddr,\n /**\n * What to use as the delimiter for the `gib`.\n *\n * @default GIB_DELIMITER\n *\n * ## notes\n *\n * This is not the same thing necessarily as the ib^gib delimiter.\n * In fact the default gibDelimiter ATOW ('.') is different than the\n * default ib^gib delimiter ('^').\n */\n gibDelimiter?: string,\n /**\n * If this is primitive, then the `gib` is always GIB (\"gib\" string literal).\n */\n isPrimitive?: boolean,\n /**\n * Hash algorithm to use when calculating the gib hash of the ibgib datum.\n *\n * ## notes\n *\n * * I'm just including this now to show where we will expand when working with\n * multiple hash algorithms. For now though, in all of V1, we use 'SHA-256'\n * when calculating the gib hashes. This is why I'm hard-coding the type\n * here instead of using this lib's `HashAlgorithm` type.\n * * This param is actually ignored ATOW.\n * * In my current consuming use case (ionic-gib), though,\n * I am indeed using SHA-512 when encrypting using encrypt-gib. I only note\n * this in case someone sees \"SHA-512\" code somewhere and is confused.\n */\n hashAlgorithm?: 'SHA-256',\n}): Promise<string> {\n const lc = `[${getGib.name}]`;\n try {\n if (!ibGib) { throw new Error(`ibGib required. (E: 17d073226b9d42fd841e5a94b065ef21)`); }\n if (isPrimitive) { return GIB; }\n const ibGibHash = await sha256v1(ibGib, '');\n const rel8ns = ibGib.rel8ns ?? {};\n const data = ibGib.data ?? {};\n gibDelimiter = gibDelimiter || GIB_DELIMITER;\n if (!hasTjp) { hasTjp = (rel8ns.tjp ?? []).length > 0 || data.isTjp || false; }\n if (hasTjp) {\n let tjpAddrGib: string | undefined;\n if (rel8ns.tjp) {\n if (rel8ns.tjp.length === 1) {\n if (rel8ns.tjp[0]) { // checking for empty string\n tjpAddr = rel8ns.tjp[0];\n } else {\n throw new Error(`rel8ns.tjp[0] is falsy. (E: ed879d2b039543f8b1902e8b7b5a5a7b)`);\n }\n } else if (rel8ns.tjp.length > 1) {\n if (rel8ns.tjp[rel8ns.tjp.length - 1]) {\n console.warn(`${lc} found more than one tjp addr...only expecting 1 ATOW. (W: 10ed43f716e743e0afd1954f1ab46789)`);\n tjpAddr = rel8ns.tjp[rel8ns.tjp.length - 1];\n } else {\n throw new Error(`multiple tjp addrs, and the last (most recent) one is falsy. (E: bc835dc89be24075bba8b2b6616ea069)`);\n }\n } else {\n // empty rel8ns.tjp array?\n throw new Error(`hasTjp is true but rel8ns.tjp is empty array. (E: d08b2f9e86494814b5e7d7b4602b2ab7)`);\n }\n } else if (data.isTjp) {\n // the ibGib itself is the tjp\n tjpAddr = getIbGibAddr({ ib: ibGib.ib, gib: ibGibHash });\n } else {\n throw new Error(`hasTjp is true, but both ibGib.rel8ns.tjp and ibGib.data.isTjp are falsy. (E: 4e246897e52044789594d853bb5b66ee)`)\n }\n tjpAddrGib = tjpAddr ? getIbAndGib({ ibGibAddr: tjpAddr }).gib : undefined;\n\n if (tjpAddrGib) {\n // if the ibGib IS the tjp, then the gib is only the hash\n\n // if the ibGib is NOT the tjp, then the gib is the hash plus\n // tjpGib. note in the future, if multiple tjps are going, then\n // tjpAddrGib itself may have another delim inside it, so we\n // will end up with a gib with multiple delimiters.\n return data.isTjp ? ibGibHash : `${ibGibHash}${GIB_DELIMITER}${tjpAddrGib}`;\n } else {\n throw new Error(`hasTjp is true but could not find tjpAddrGib. (E: 1863df626b754744a1d431a683cb0ba0)`);\n }\n } else {\n // no tjp, so gib is just the hash\n return ibGibHash;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n\n}\n\n/**\n * Parses gib (either via `gib` param or `ibGibAddr.gib`) and returns information\n * about it.\n *\n * @returns Information about the given `gib` (or `gib` extracted from `ibGibAddr`)\n */\nexport function getGibInfo({\n ibGibAddr,\n gib,\n gibDelimiter,\n}: {\n /**\n * If given, will extract `gib` from this.\n */\n ibGibAddr?: IbGibAddr,\n /**\n * `gib` to analyze.\n */\n gib?: Gib,\n /**\n * Delimiter among pieces of gib, if applicable.\n *\n * @default GIB_DELIMITER (ATOW '.')\n *\n * ## notes\n *\n * Some `gib` values will include tjp information, while others\n * are just the hash.\n */\n gibDelimiter?: string,\n}): GibInfo {\n const lc = `[${getGibInfo.name}]`;\n try {\n if (!ibGibAddr && !gib) { throw new Error(`Either ibGibAddr or gib required. (E: 25e3dcbe63cd44909032df12af9df75e)`); }\n gib = gib || getIbAndGib({ ibGibAddr }).gib;\n\n if (gib === GIB) { return { isPrimitive: true } }\n\n gibDelimiter = gibDelimiter ?? GIB_DELIMITER;\n\n if (gib.includes(gibDelimiter)) {\n const pieces = gib.split(gibDelimiter);\n if (pieces.some(p => p === '')) { throw new Error(`unexpected gib that contains gibDelimiter (${gibDelimiter}) but has at least one piece with empty string. (E: 75a94280045541009ee68182d12d3449)`); }\n\n const piecesCount = pieces.length;\n if (piecesCount > 2) { console.warn(`${lc} gib only expected to have two pieces ATOW. re-examine please. (W: aa4283ac5a5747a386a69966ecdad39d)`); }\n\n const punctiliarHashPiece = pieces.splice(0, 1);\n return {\n punctiliarHash: punctiliarHashPiece[0],\n tjpGib: pieces.join(gibDelimiter), // after splice, piece/s is/are tjp\n piecesCount,\n delimiter: gibDelimiter,\n }\n } else {\n return {\n punctiliarHash: gib,\n piecesCount: 1,\n delimiter: gibDelimiter,\n }\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { join } from 'node:path';\n\nimport { clone, getUUID, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { getGib, getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport {\n MetaspaceFactory, MetaspaceService, ZeroSpaceFactoryFunction,\n LocalSpaceFactoryFunction, DtoToSpaceFunction\n} from '@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs';\nimport { NodeIndexedFilesystemSpace_V1 } from '@ibgib/node-gib/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-v1.mjs';\nimport {\n NodeFilesystemSpaceData_V1, DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1,\n} from '@ibgib/node-gib/dist/witness/space/node-filesystem-space/node-filesystem-space-types.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from './server-constants.mjs';\nimport { NodeIndexedFilesystemSpaceData_V1, NodeIndexedFilesystemSpaceRel8ns_V1 } from '@ibgib/node-gib/dist/witness/space/node-filesystem-space/node-indexed-filesystem-space/node-indexed-filesystem-space-types.mjs';\nimport { Metaspace_Nodeindexedspace } from './metaspace-nodeindexedspace/metaspace-nodeindexedspace.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Deterministically calculates the physical filesystem path for a domain\n * based on its keystone's tjpGib.\n *\n * @param tjpGib The TJP hash of the keystone defining the domain.\n * @param baseDataDir The root directory for all ibgib spaces on the server.\n * @returns The absolute path to the domain's isolated root.\n */\nexport function getDomainRootPath(tjpGib: string, baseDataDir: string): string {\n // We use the first 2 characters as subfolders to balance the OS filesystem entries.\n // e.g. /data/spaces/ab/c1/defg...\n const sub1 = tjpGib.slice(0, 2);\n const sub2 = tjpGib.slice(2, 4);\n const remaining = tjpGib;\n\n return join(baseDataDir, 'domains', sub1, sub2, remaining);\n}\n\n/**\n * Creates a MetaspaceFactory using the \"Factory Closure Pattern\" to isolate\n * all space operations within the given domainRootPath.\n *\n * @param domainRootPath The physical root directory for this domain.\n * @returns A MetaspaceFactory pre-configured for this domain.\n */\nexport function getDomainFactory(domainRootPath: string): MetaspaceFactory {\n const lc = `[${getDomainFactory.name}]`;\n\n const fnZeroSpaceFactory: ZeroSpaceFactoryFunction = () => {\n const zeroSpaceData: NodeIndexedFilesystemSpaceData_V1 = {\n ...clone(DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1),\n classname: NodeIndexedFilesystemSpace_V1.name,\n baseDir: domainRootPath,\n };\n\n const zeroSpace = new NodeIndexedFilesystemSpace_V1(zeroSpaceData);\n zeroSpace.gib = 'gib'; // Primitive zero space\n return zeroSpace;\n };\n\n const fnDefaultLocalSpaceFactory: LocalSpaceFactoryFunction = async (opts) => {\n // Ensure we don't prompt for a name during server bootstrap\n // opts.spaceName ||= `default_${pickRandom_Letters({ count: 5 })}`;\n opts.spaceName ||= `default`;\n\n const spaceData: NodeFilesystemSpaceData_V1 = {\n ...clone(DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1),\n classname: NodeIndexedFilesystemSpace_V1.name,\n uuid: await getUUID(),\n baseDir: domainRootPath,\n name: opts.spaceName,\n spaceSubPath: opts.spaceName,\n baseSubPath: 'ibgib',\n binSubPath: 'bin',\n dnaSubPath: 'dna',\n ibgibsSubPath: 'ibgibs',\n metaSubPath: 'meta',\n isTjp: true,\n };\n if (logalot) { console.log(`${lc}[${fnDefaultLocalSpaceFactory.name}] spaceData.classname: ${spaceData.classname} (I: b60da661e9282e1253101e08765eb226)`); }\n\n const space = new NodeIndexedFilesystemSpace_V1(spaceData);\n space.gib = await getGib({ ibGib: space as any, hasTjp: true });\n\n return space;\n };\n\n const fnDtoToSpace: DtoToSpaceFunction = async (spaceDto: IbGib_V1) => {\n if (!spaceDto) { throw new Error(`spaceDto required (E: 30ede52f9c974591dac980a810510e26)`); }\n if (!spaceDto.data) { throw new Error(`spaceDto.data required (E: 867b08a9c998e95028396f283d1d4826)`); }\n if (!spaceDto.data.classname) { throw new Error(`spaceDto.data.classname required (E: 95a68813e64e68e6c84296d8dbaeb826)`); }\n if (spaceDto.data.classname !== NodeIndexedFilesystemSpace_V1.name) {\n throw new Error(`spaceDto.data.classname (${spaceDto.data.classname}) expeced to be ${NodeIndexedFilesystemSpace_V1.name} (E: 68aaa875ff22b92f57a0a3189da4b826)`);\n }\n\n const space = await NodeIndexedFilesystemSpace_V1.createFromDto(\n spaceDto as IbGib_V1<NodeIndexedFilesystemSpaceData_V1, NodeIndexedFilesystemSpaceRel8ns_V1>\n );\n return space;\n };\n\n\n return {\n fnZeroSpaceFactory,\n fnDefaultLocalSpaceFactory,\n fnDtoToSpace,\n };\n}\n\n/**\n * Orchestrates the bootstrapping of a domain-isolated metaspace.\n *\n * @param keystoneAddr The full address of the keystone defining the domain.\n * @param baseDataDir The server's root data directory.\n * @returns An initialized MetaspaceService scoped to the domain.\n */\nexport async function bootstrapDomainMetaspace(\n keystoneAddr: string,\n baseDataDir: string\n): Promise<MetaspaceService> {\n const { tjpGib, punctiliarHash } = getGibInfo({ ibGibAddr: keystoneAddr });\n const domainGib = tjpGib || punctiliarHash;\n if (!domainGib) {\n throw new Error(`Could not extract tjpGib from keystone address: ${keystoneAddr}`);\n }\n\n const domainRootPath = getDomainRootPath(domainGib, baseDataDir);\n const factory = getDomainFactory(domainRootPath);\n\n const metaspace = new Metaspace_Nodeindexedspace(/*cacheSvc*/ undefined);\n\n await metaspace.initialize({\n metaspaceFactory: factory,\n // For server-side, these prompts should probably be non-interactive or log errors.\n getFnAlert: () => async (arg) => console.log(`[ALERT] ${arg.title}: ${arg.msg}`),\n getFnPrompt: () => async (arg) => { throw new Error(`Interactive prompt (${arg.title}) not supported in server bootstrap.`); },\n getFnPromptPassword: () => async (title) => { throw new Error(`Password prompt (${title}) not supported in server bootstrap.`); },\n });\n\n return metaspace;\n}\n", "import { existsSync, mkdirSync } from 'node:fs';\nimport { writeFile, rm, readFile, readdir } from 'node:fs/promises';\nimport { default as pathUtils, join } from 'path';\n\nimport { clone, extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbAndGib, getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { IbGib_V1, IbGibRel8ns_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { toDto, isBinary, } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';\nimport {\n PutIbGibFileOpts, PutIbGibFileResult, GetIbGibFileOpts, GetIbGibFileResult,\n DeleteIbGibFileOpts, DeleteIbGibFilesResult,\n} from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-types.mjs';\nimport { isMetaStone, parseMetaStoneIb } from '@ibgib/core-gib/dist/common/meta-stone/meta-stone-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../../constants.mjs';\nimport { NodeFilesystemSpace_V1 } from '../node-filesystem-space-v1.mjs';\nimport { DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1, NodeFilesystemSpaceData_V1, NodeFilesystemSpaceRel8ns_V1 } from '../node-filesystem-space-types.mjs';\nimport { DEFAULT_NODE_INDEXED_FILESYSTEM_SPACE_DATA_V1 } from './node-indexed-filesystem-space-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nconst INDEX_DIR_NAME = '.idx';\nconst MAP_EXTENSION = '.map';\n\n/**\n * Mapping from Full IbGib Address -> Short Filename\n */\ninterface IndexMap {\n [addr: string]: string;\n}\n\n/**\n * Robust filesystem space that uses a distributed index folder strategy (.idx)\n * to avoid Windows MAX_PATH issues while maintaining TJP grouping.\n */\nexport class NodeIndexedFilesystemSpace_V1<\n TData extends NodeFilesystemSpaceData_V1 = NodeFilesystemSpaceData_V1,\n TRel8ns extends NodeFilesystemSpaceRel8ns_V1 = NodeFilesystemSpaceRel8ns_V1\n> extends NodeFilesystemSpace_V1<TData, TRel8ns> {\n\n protected override lc: string = `[${NodeIndexedFilesystemSpace_V1.name}]`;\n\n /**\n * in case the caller tries to override the classname. This should be overridden in any descendant classes\n */\n get classname(): string { return NodeIndexedFilesystemSpace_V1.name; }\n\n /**\n * Factory static method to create the space with the given\n * `dto` param's ibGib properties.\n *\n * We do this because when we persist this space (and its settings\n * located in `data`), we do not save the actual class instantiation\n * but just the ibgib properties. Use this factory method to\n * create a new space instance and rehydrate from that saved dto.\n *\n * ## notes\n *\n * * DTO stands for data transfer object.\n *\n * @param dto space ibGib dto that we're going to load from\n * @returns newly created space built upon `dto`\n */\n static async createFromDto<\n TData extends NodeFilesystemSpaceData_V1 = NodeFilesystemSpaceData_V1,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n >(dto: IbGib_V1<TData, TRel8ns>): Promise<NodeFilesystemSpace_V1<TData, TRel8ns>> {\n const lc = `[${NodeIndexedFilesystemSpace_V1.name}][${this.createFromDto.name}]`;\n if (logalot) { console.log(`${lc}`); }\n const space = new NodeIndexedFilesystemSpace_V1<TData, TRel8ns>(dto.data); // shouldn't have to do this\n await space.initialized;\n await space.loadIbGibDto(dto);\n return space;\n }\n\n constructor(\n // /**\n // * Default predicate value when putting an unknown ibGib.\n // *\n // * ## notes\n // *\n // * So when a repo witnesses another ibGib, it either defaults to\n // * storing that ibGib or not storing that ibGib. This is what that\n // * is referring to. If it's optimistic, then it stores any ibGib by\n // * default and it passes its put predicate.\n // */\n // public optimisticPut: boolean = true,\n initialData?: TData,\n initialRel8ns?: TRel8ns,\n ) {\n super(initialData ?? clone(DEFAULT_NODE_INDEXED_FILESYSTEM_SPACE_DATA_V1), initialRel8ns);\n const lc = `${this.lc}[ctor]`;\n\n // try {\n // if (logalot) { console.log(`${lc} starting...`); }\n // this.initialize();\n // } catch (error) {\n // console.error(`${lc} ${extractErrorMsg(error)}`);\n // throw error;\n // } finally {\n // if (logalot) { console.log(`${lc} complete.`); }\n // }\n }\n\n /**\n * Overrides the path building to be \"Index Aware\".\n * In this implementation, the \"path\" returned is the bucket directory.\n * The actual filename is resolved via the index.\n */\n protected override async buildPath(opts: any): Promise<string> {\n const { addr, isDna, isBin, addrIsForAMetaStone } = opts;\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n\n // Primitive ibgibs do not need bucket indexing, delegate to original un-indexed logic\n if (gib === 'gib') {\n return super.buildPath(opts);\n }\n\n let subPath = '';\n if (isDna) { subPath = this.data!.dnaSubPath!; }\n else if (isBin) { subPath = this.data!.binSubPath!; }\n else if (addrIsForAMetaStone || isMetaStone({ addr })) { subPath = this.data!.metaSubPath!; }\n else { subPath = this.data!.ibgibsSubPath!; }\n\n return this.buildPath_withSubPath({ addr, subPath });\n }\n\n protected async buildPath_withSubPath(opts: { addr: string, subPath: string }): Promise<string> {\n const { addr, subPath } = opts;\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n\n // Deterministic Bucket based on first 6 chars of gib (or ib if gib is primitive)\n let hashBase = (gib && gib !== 'gib') ? gib : ib;\n\n // Special handling for metastones: group by target TJP\n if (isMetaStone({ addr })) {\n hashBase = parseMetaStoneIb({ ib }).tjpGib;\n } else {\n const gibInfo = getGibInfo({ ibGibAddr: addr });\n if (gibInfo.tjpGib) {\n hashBase = gibInfo.tjpGib;\n }\n }\n\n const bucket1 = hashBase.substring(0, 3).toUpperCase();\n const bucket2 = hashBase.substring(3, 6).toUpperCase();\n\n // Root/Space/SubPath/B1/B2\n return pathUtils.join(\n this.data!.baseSubPath!,\n this.data!.spaceSubPath!,\n subPath,\n bucket1,\n bucket2\n );\n }\n\n /**\n * Resolves the actual filename for an address using the index.\n */\n protected async resolveFilename(bucketPath: string, addr: string): Promise<string | undefined> {\n const mapFilePath = this.getMapFilePath(bucketPath, addr);\n if (!existsSync(mapFilePath)) { return undefined; }\n\n try {\n const content = await readFile(mapFilePath, 'utf8');\n const map: IndexMap = JSON.parse(content);\n return map[addr];\n } catch (error) {\n console.error(`${this.lc} Error reading map file ${mapFilePath}: ${extractErrorMsg(error)}`);\n return undefined;\n }\n }\n\n /**\n * Updates the index with a new mapping.\n */\n protected async updateIndex(bucketPath: string, addr: string, filename: string): Promise<void> {\n const indexDir = join(bucketPath, INDEX_DIR_NAME);\n if (!existsSync(indexDir)) {\n mkdirSync(indexDir, { recursive: true });\n }\n\n const mapFilePath = this.getMapFilePath(bucketPath, addr);\n let map: IndexMap = {};\n\n if (existsSync(mapFilePath)) {\n try {\n const content = await readFile(mapFilePath, 'utf8');\n map = JSON.parse(content);\n } catch (error) {\n console.warn(`${this.lc} Map file ${mapFilePath} corrupted, overwriting. (W: 4129bd5e921d4d8e87491d9e2a84423)`);\n }\n }\n\n map[addr] = filename;\n await writeFile(mapFilePath, JSON.stringify(map, null, 2));\n }\n\n protected getMapFilePath(bucketPath: string, addr: string): string {\n const { gib } = getIbAndGib({ ibGibAddr: addr });\n // Use next 4 chars of hash for map filename distribution\n const mapName = (gib.length > 10 ? gib.substring(6, 10) : 'default').toUpperCase();\n return join(bucketPath, INDEX_DIR_NAME, `${mapName}${MAP_EXTENSION}`);\n }\n\n protected override async putFile(opts: PutIbGibFileOpts): Promise<PutIbGibFileResult> {\n const lc = `${this.lc}[putFile]`;\n const { ibGib, isDna } = opts;\n if (!ibGib) { throw new Error('ibGib required'); }\n\n const addr = getIbGibAddr({ ibGib });\n const { gib } = getIbAndGib({ ibGibAddr: addr });\n\n // Primitive ibgibs bypass indexing completely\n if (gib === 'gib') {\n return super.putFile(opts);\n }\n\n const bucketPath = join(this.data!.baseDir, await this.buildPath({\n addr, isDna, isBin: isBinary({ addr }), addrIsForAMetaStone: isMetaStone({ addr })\n }));\n\n if (!existsSync(bucketPath)) {\n mkdirSync(bucketPath, { recursive: true });\n }\n\n // 1. Resolve or Generate Filename\n let filename = await this.resolveFilename(bucketPath, addr);\n if (!filename) {\n // Generate a random but safe filename\n const randomId = Math.random().toString(36).substring(2, 8);\n filename = `${randomId}.json`;\n }\n\n const fullPath = join(bucketPath, filename);\n\n // 2. Write Data\n try {\n const data = JSON.stringify(toDto({ ibGib }), null, 2);\n await writeFile(fullPath, data, this.data!.encoding as BufferEncoding);\n\n // 3. Update Index\n await this.updateIndex(bucketPath, addr, filename);\n return { success: true };\n } catch (error) {\n return { success: false, errorMsg: extractErrorMsg(error) };\n }\n }\n\n protected override async getFile(opts: GetIbGibFileOpts): Promise<GetIbGibFileResult> {\n const lc = `${this.lc}[getFile]`;\n const addr = opts.addr;\n if (!addr) { throw new Error('addr required'); }\n\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n\n // Primitive ibgibs bypass indexing completely\n if (gib === 'gib') {\n return super.getFile(opts);\n }\n\n const isBin = isBinary({ addr });\n const addrIsMetaStone = isMetaStone({ addr });\n\n // Build list of subpaths to try\n const subPathsToTry: string[] = [];\n\n if (opts.isDna) {\n subPathsToTry.push(this.data!.dnaSubPath!);\n } else if (isBin) {\n subPathsToTry.push(this.data!.binSubPath!);\n } else if (addrIsMetaStone) {\n subPathsToTry.push(this.data!.metaSubPath!);\n } else {\n // Might be DNA if not explicitly told, check dna first as optimization if ib is a transform\n const { ib } = getIbAndGib({ ibGibAddr: addr });\n const knownTransformIbs = ['fork', 'mut8', 'rel8', 'plan'];\n const addrMightBeDna = knownTransformIbs.some(x => x === ib || x.startsWith(ib + ' '));\n\n if (addrMightBeDna) {\n subPathsToTry.push(this.data!.dnaSubPath!);\n }\n subPathsToTry.push(this.data!.ibgibsSubPath!);\n if (!addrMightBeDna) {\n subPathsToTry.push(this.data!.dnaSubPath!);\n }\n }\n\n for (const subPath of subPathsToTry) {\n const relBucketPath = await this.buildPath_withSubPath({ addr, subPath });\n const bucketPath = join(this.data!.baseDir, relBucketPath);\n const filename = await this.resolveFilename(bucketPath, addr);\n if (filename) {\n const fullPath = join(bucketPath, filename);\n if (existsSync(fullPath)) {\n try {\n const content = await readFile(fullPath, 'utf8');\n const ibGib = JSON.parse(content) as IbGib_V1;\n return { success: true, ibGib };\n } catch (error) {\n if (logalot) { console.error(`${lc} error reading ${fullPath}: ${extractErrorMsg(error)}`); }\n }\n }\n }\n }\n\n return { success: true };\n }\n\n protected override async deleteFile(opts: DeleteIbGibFileOpts): Promise<DeleteIbGibFilesResult> {\n const addr = opts.addr;\n if (!addr) { throw new Error('addr required'); }\n\n const { gib } = getIbAndGib({ ibGibAddr: addr });\n\n // Primitive ibgibs bypass indexing completely\n if (gib === 'gib') {\n return super.deleteFile(opts);\n }\n\n const bucketPath = join(this.data!.baseDir, await this.buildPath({\n addr, isDna: opts.isDna, isBin: isBinary({ addr }), addrIsForAMetaStone: isMetaStone({ addr })\n }));\n\n const filename = await this.resolveFilename(bucketPath, addr);\n if (!filename) { return { success: true }; }\n\n const fullPath = join(bucketPath, filename);\n try {\n if (existsSync(fullPath)) {\n await rm(fullPath);\n }\n\n // Remove from index\n const mapFilePath = this.getMapFilePath(bucketPath, addr);\n if (existsSync(mapFilePath)) {\n const content = await readFile(mapFilePath, 'utf8');\n const map: IndexMap = JSON.parse(content);\n delete map[addr];\n if (Object.keys(map).length === 0) {\n await rm(mapFilePath);\n } else {\n await writeFile(mapFilePath, JSON.stringify(map, null, 2));\n }\n }\n return { success: true };\n } catch (error) {\n return { success: false, errorMsg: extractErrorMsg(error) };\n }\n }\n\n /**\n * Overrides getMetaStoneAddrs to look in the bucketed directory.\n */\n protected override async getMetaStoneAddrs(opts: {\n ibGibAddr: string,\n tjpGib: string,\n fnFilterIb?: (ib: string) => boolean,\n }): Promise<string[]> {\n const { ibGibAddr, tjpGib, fnFilterIb } = opts;\n const lc = `${this.lc}[getMetaStoneAddrs]`;\n\n // Get the bucket path for metastones for this TJP\n const relBucketPath = await this.buildPath({\n addr: ibGibAddr,\n addrIsForAMetaStone: true\n });\n const bucketPath = join(this.data!.baseDir, relBucketPath);\n\n if (!existsSync(bucketPath)) { return []; }\n\n const indexDir = join(bucketPath, INDEX_DIR_NAME);\n if (!existsSync(indexDir)) { return []; }\n\n const metaStoneAddrs: string[] = [];\n\n try {\n const mapFiles = (await readdir(indexDir)).filter(f => f.endsWith(MAP_EXTENSION));\n\n for (const mapFile of mapFiles) {\n const content = await readFile(join(indexDir, mapFile), 'utf8');\n const map: IndexMap = JSON.parse(content);\n for (const addr of Object.keys(map)) {\n if (isMetaStone({ addr })) {\n const { ib } = getIbAndGib({ ibGibAddr: addr });\n const metaStoneInfo = parseMetaStoneIb({ ib });\n if (metaStoneInfo.tjpGib === tjpGib) {\n if (!fnFilterIb || fnFilterIb(ib)) {\n metaStoneAddrs.push(addr);\n }\n }\n }\n }\n }\n } catch (error) {\n if (logalot) { console.error(`${lc} error reading metastone index: ${extractErrorMsg(error)}`); }\n }\n\n return metaStoneAddrs;\n }\n}\n", "/**\n * The core of the simplicity of the ibGib protocol is that you are\n * taking two (or more) ibGibs and producing other ibGibs.\n *\n * There are three primary functions: mut8, rel8, fork\n *\n * These are actually different aspects of the single function of\n * relationship and time, either:\n * 1) Creating a 'new' timeline, or...\n * 2) Extending an existing one.\n *\n * Mut8 is intrinsic, rel8 is extrinsic, fork is a new timeline.\n * Mut8 changes a timeline, rel8 changes a timeline's link(s),\n * fork creates a new timeline.\n */\nimport {\n IbGibRel8ns, IbGibAddr, IbGibWithDataAndRel8ns, Gib,\n} from '../types.mjs';\n\n/**\n * Need to see if I can remove this...\n */\nexport declare type IbGibData_V1 = {\n [key: string]: any;\n /**\n * if true, this is the very first ibgib in a timeline.\n *\n * in the future, it is possible that there will be multiple temporal\n * junction points and that this may be true for multiple ibgibs in a\n * timeline. but atow (02/2024) and the foreseeable future, this should only\n * be true for the very first ibgib.\n *\n */\n isTjp?: boolean;\n /**\n * special property meant to track evolution count. So when a transform is\n * applied to a punctiliar ibgib, this value is incremented if that ibgib\n * has a temporal junction point (tjp).\n */\n n?: number;\n /**\n * the timestamp that the ibgib was created/evolved. to get the\n * milliseconds, get/set {@link timestampMs}\n */\n timestamp?: string;\n /**\n * the ms component of {@link timestamp}\n */\n timestampMs?: number;\n /**\n * if given, this is the unique identification for the ibgib. note that\n * there is often a good use case for this when linking multiple ibgibs\n * together in some operation. but usually this is a convenience property.\n * most actual identification should often be done with the ib^gib address,\n * either the tjp or punctiliar address depending on use case.\n */\n uuid?: string;\n};\n\n/**\n * Convenience enum to avoid spelling mistakes. (optional)\n */\nexport enum Rel8n {\n past = 'past',\n ancestor = 'ancestor',\n dna = 'dna',\n identity = 'identity',\n tjp = 'tjp',\n secret = 'secret',\n encryption = 'encryption',\n}\n/**\n * shape of named edges (hard links) to other ibgibs which forms a dependency\n * graph (DAG) in V1.\n *\n * Note that all rel8ns are open-ended, because this is how rel8ns actually\n * exist. For example, consider that any relationship conceived nowadays in CS\n * as one-to-one, actually can be thought of as many-to-many when considering\n * multiple timelines.\n */\nexport interface IbGibRel8ns_V1 extends IbGibRel8ns {\n /**\n * when an ibgib is evolved, this is a rel8n to pointer(s) in the ibgib\n * timeline's history.\n *\n * depending on use case, this could only be a single pointer to the most\n * recent past (like a linked list or blockchain), or it could be the entire\n * history from inception of the ibgib.\n * @optional\n */\n [Rel8n.past]?: IbGibAddr[];\n /**\n * associate the owner/producer of the ibgib. not in use atow (02/2024), so\n * this may change or be yagni. the keystone structure will solve this.\n * @optional\n */\n [Rel8n.identity]?: IbGibAddr[];\n /**\n * when an ibgib is forked, this is the parent.\n * @optional\n */\n [Rel8n.ancestor]?: IbGibAddr[];\n /**\n * points to the dna that are the history of applied transforms that got the\n * ibgib to its current state.\n * @optional\n */\n [Rel8n.dna]?: IbGibAddr[];\n /**\n * temporal junction point of the ibgib.\n *\n * this is set if either uuid or timestamp tjp setting is used when the most\n * recent transform was applied.\n * @optional\n */\n [Rel8n.tjp]?: IbGibAddr[];\n /**\n * if there is any encryption related to this ibgib, most likely for\n * enciphering one or more properties in the ibgib's `ib` and/or `data`\n * properties, the associated secret(s) can be linked here.\n * @optional\n */\n [Rel8n.secret]?: IbGibAddr[];\n /**\n * if there is any encryption related to this ibgib, most likely for\n * enciphering one or more properties in the ibgib's `ib` and/or `data`\n * properties, the encryption ibgibs (which hold encryption details like\n * encryption algorithm + parameterization) can be linked here.\n * @optional\n */\n [Rel8n.encryption]?: IbGibAddr[];\n}\n/**\n * combined shape of the overall v1 ibgib. it has an ib, gib, data, and rel8ns. */\nexport interface IbGib_V1<TData = IbGibData_V1, TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1>\n extends IbGibWithDataAndRel8ns<TData, TRel8ns> {\n}\n\nexport interface GibInfo {\n /**\n * Hash for this ibgib frame in time.\n */\n punctiliarHash?: string;\n /**\n * The gib for this ibgib's most recent tjp.\n *\n * ## notes\n *\n * ATOW, only one tjp expected really, though I've been coding\n * with the possibility of having multiple tjp's similar to\n * checkpoints.\n */\n tjpGib?: Gib;\n /**\n * If\n */\n piecesCount?: number;\n /**\n * If a delimiter is used in this gib, this is the delimiter.\n *\n * ## notes\n *\n * ATOW, the caller already knows the delimiter. But I'm thinking that\n * I may be persisting this at some point and it would be good to include.\n */\n delimiter?: string;\n /**\n * True the gib is just 'gib' (GIB constant), else falsy.\n */\n isPrimitive?: boolean;\n}\n", "import { getIbGibAddr } from '../../helper.mjs';\nimport { clone, getUUID, getTimestamp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { sha256v1 } from '../sha256v1.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1, Rel8n } from '../types.mjs';\nimport { TransformOpts_Fork, TransformResult } from '../../types.mjs';\nimport { IBGIB_DELIMITER, ROOT_ADDR } from '../constants.mjs';\nimport { buildDna } from './transform-helper.mjs';\n\n/**\n * Original-ish V1 transform behavior.\n * Going to create an ibGib containing the fork data.\n * Apply that fork and create a resulting ibGib.\n *\n * Takes the src ibGib, clears its past and adds a link to\n * the src via the 'ancestor' rel8n.\n *\n * NOTE:\n * This is NOT going to do the plan^gib stuff ATM.\n * Also this does NOT add any identity information ATM.\n */\nexport async function fork(opts: TransformOpts_Fork<IbGib_V1>): Promise<TransformResult<IbGib_V1>> {\n const {\n noTimestamp, dna,\n linkedRel8ns,\n destIb, uuid, tjp,\n cloneRel8ns, cloneData,\n type = 'fork',\n } = opts;\n let src = opts.src;\n\n const lc = '[fork_v1]';\n // #region validation\n if (type !== 'fork') { throw new Error(`${lc} not a fork transform.`); }\n if (!opts.type) { opts.type = 'fork' }\n\n if (!src) { throw new Error(`${lc} src required to fork.`); }\n if (!src!.ib) { throw new Error(`${lc} src.ib required.`); }\n // destIb is not required, as it just reuses src.ib\n if (destIb && destIb.includes(IBGIB_DELIMITER)) {\n throw new Error(`${lc} destIb can't contain (hardcoded) delimiter right now.`);\n }\n if (!src!.gib) { throw new Error(`${lc} src.gib required.`); }\n\n // #endregion\n\n // we want to forget `src` proper very quickly because it may have other\n // non-IbGib properties that are not relevant to our transform.\n let dto: IbGib_V1 = { ib: src.ib, gib: src.gib, };\n if (src.data && Object.keys(src.data).length > 0) { dto.data = src.data; }\n if (src.rel8ns && Object.keys(src.rel8ns).length > 0) { dto.rel8ns = src.rel8ns; }\n src = dto;\n\n const srcAddr = getIbGibAddr({ ib: src!.ib, gib: src.gib });\n opts.srcAddr = srcAddr;\n\n const rel8ns: IbGibRel8ns_V1 =\n cloneRel8ns && src.rel8ns && Object.keys(src.rel8ns).length > 0 ?\n clone(src.rel8ns) :\n {};\n delete rel8ns.past;\n const data: any = cloneData && src?.data ? clone(src!.data) : {};\n if (opts.nCounter) { data.n = 0; }\n const ancestor = linkedRel8ns?.includes(Rel8n.ancestor) ?\n [srcAddr] :\n (rel8ns.ancestor || []).concat([srcAddr]);\n rel8ns.ancestor = ancestor;\n\n // remove tjp if exists in rel8ns\n if (rel8ns.tjp) { delete rel8ns.tjp; }\n\n const newIbGib = clone(src) as IbGib_V1<IbGibData_V1>;\n if (noTimestamp && tjp?.timestamp) {\n throw new Error(`${lc} both noTimestamp and tjp.timestamp selected.`);\n }\n if (!noTimestamp || tjp?.timestamp) {\n const date = new Date();\n data.timestamp = getTimestamp(date);\n data.timestampMs = date.getMilliseconds();\n }\n if (tjp?.uuid || uuid) { data.uuid = await getUUID(); }\n if (tjp?.uuid || tjp?.timestamp) {\n data.isTjp = true;\n } else {\n if (data.isTjp) { delete data.isTjp; }\n }\n\n newIbGib.ib = destIb || 'ib';\n // rel8ns ignored if forking from the root ib^gib\n if (srcAddr !== ROOT_ADDR) { newIbGib.rel8ns = rel8ns; }\n if (Object.keys(data).length > 0) { newIbGib.data = data; }\n\n let transformDna: IbGib_V1 | null = null;\n if (dna) {\n transformDna = await buildDna(opts);\n const dnaAddr = getIbGibAddr({ ibGib: transformDna });\n rel8ns.dna = linkedRel8ns?.includes(Rel8n.dna) ?\n rel8ns.dna = [dnaAddr] :\n rel8ns.dna = (rel8ns.dna || []).concat(dnaAddr);\n }\n\n newIbGib.gib = await sha256v1(newIbGib, '');\n\n const result: TransformResult<IbGib_V1> = { newIbGib };\n if (transformDna) { result.dnas = [transformDna!] }\n return result;\n}\n", "import { getIbGibAddr } from '../../helper.mjs';\nimport { clone, getTimestamp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1, Rel8n } from '../types.mjs';\nimport { TransformOpts_Mut8, TransformResult } from '../../types.mjs';\nimport { IBGIB_DELIMITER, } from '../constants.mjs';\nimport { buildDna, isPrimitive, getGib } from './transform-helper.mjs';\n\n/**\n * Original-ish V1 transform behavior.\n * Going to create a new ibGib which mut8s internal data (or the ib) from the src ibgib.\n *\n * Takes the immutable src ibGib record, applies a mutation to its internal (intrinsic)\n * `data` field, creates a new ibGib with the new intrinsic data.\n *\n * ### remember, ibgib basic structure\n *\n * Remember, the ibGib has the following basic structure (here represented in JSON):\n * {\n * ib: 'some ib, can be a simple name, or other metadata, up to very complex metadata.',\n * gib: 'ABC123', // hash of the other three fields of our JSON data structure\n * rel8ns: {\n * 'link name': [ 'other ibgib^ABC345', 'yo^456789' ],\n * 'called an edge in other jargon': [ 'ib^gib' ],\n * 'past': ['ib^gib']\n * ...\n * },\n * data: {\n * 'intrinsic data': 'intrinsic value',\n * 'copied each datum': 'so should be relatively small in practice',\n * 'can...': {\n * '...also be objects if you really': ['want']\n * }\n * }\n * }\n *\n * So this transform is primarily concerned with that `data` property (though we can mut8 the ib also).\n * If it's really anything complex, most likely it would be better to do\n * another ibGib and link to it via the `rel8ns` (in the same way that in OOP it\n * is good to have single responsibility for class architecture).\n *\n * ### what we can do with mutations\n *\n * We can mutate the `ib` value. So if we need to change metadata (e.g. a 'rename'), we can.\n * This has implications for updating pointer refs and the tjp, but that's more advanced.\n *\n * We can also mutate the intrinsic `data` property, which is basically a JS object style of\n * key/value store.\n *\n * ### notes\n * * This is NOT going to do the plan^gib stuff ATM.\n * * This does NOT add any identity information ATM.\n *\n */\nexport async function mut8<TNewData = any>(\n opts: TransformOpts_Mut8<IbGib_V1, TNewData>\n): Promise<TransformResult<IbGib_V1>> {\n const {\n noTimestamp, dna, linkedRel8ns,\n dataToRename, dataToRemove, dataToAddOrPatch,\n mut8Ib,\n type = 'mut8'\n } = opts;\n let src = opts.src;\n const lc = '[mut8_v1]';\n // #region validation\n\n if (type !== 'mut8') { throw new Error(`${lc} not a mut8 transform.`); }\n if (!opts.type) { opts.type = 'mut8' }\n\n if (!src) { throw new Error(`${lc} src required to mut8.`); }\n if (!src!.ib) { throw new Error(`${lc} src.ib required.`); }\n if (src!.ib!.includes(IBGIB_DELIMITER)) {\n throw new Error(`${lc} ib can't contain hardcoded delimiter (${IBGIB_DELIMITER}) right now.`);\n }\n if (!src!.gib) { throw new Error(`${lc} src.gib required.`); }\n\n if (!mut8Ib && !dataToRename && !dataToRemove && !dataToAddOrPatch) {\n throw new Error(`${lc} gotta provide either a mut8Ib or some data to change.`);\n }\n\n const srcAddr = getIbGibAddr({ ib: src!.ib, gib: src.gib });\n if (opts.srcAddr && srcAddr !== opts.srcAddr) { throw new Error(`${lc} srcAddr from src does not equal opts.srcAddr`); }\n opts.srcAddr = srcAddr;\n\n // const srcIsPrimitive = src.gib === GIB || !src.gib;\n // if (srcIsPrimitive) { throw new Error(`${lc} cannot mutate primitive ibgib`); }\n if (isPrimitive({ ibGib: src })) { throw new Error(`${lc} cannot mutate primitive ibgib`); }\n\n // #endregion\n\n // we want to forget `src` proper very quickly because it may have other\n // non-IbGib properties that are not relevant to our transform.\n let dto: IbGib_V1 = { ib: src.ib, gib: src.gib, };\n if (src.data && Object.keys(src.data).length > 0) { dto.data = src.data; }\n if (src.rel8ns && Object.keys(src.rel8ns).length > 0) { dto.rel8ns = src.rel8ns; }\n src = dto;\n\n const newIbGib = clone(src) as IbGib_V1<IbGibData_V1>;\n\n const srcRel8ns = src.rel8ns ? src.rel8ns : {};\n const rel8ns: IbGibRel8ns_V1 = clone(srcRel8ns);\n rel8ns.past = linkedRel8ns?.includes(Rel8n.past) ?\n [srcAddr] :\n (rel8ns.past || []).concat([srcAddr]);\n\n let data: any = src?.data ? clone(src!.data) : {};\n if (dataToRename) { data = renameOrRemove(data, dataToRename, 'rename'); }\n if (dataToRemove) { data = renameOrRemove(data, dataToRemove, 'remove'); }\n if (dataToAddOrPatch) { data = patch(data, dataToAddOrPatch); }\n if (!noTimestamp) {\n const date = new Date();\n data.timestamp = getTimestamp(date);\n data.timestampMs = date.getMilliseconds();\n }\n\n // n-related\n if (opts.nCounter || Object.keys(data).includes('n')) {\n if (Object.keys(data).includes('n')) {\n if (Number.isInteger(data.n)) {\n if (data.n >= 0) {\n data.n = data.n + 1;\n } else {\n console.warn(`${lc} data.n is less than 0, which is unexpected. Resetting data.n to 0.`);\n data.n = 0;\n }\n } else {\n throw new Error('cannot increment nCounter because data.n is not a number.');\n }\n } else {\n data.n = 0;\n }\n }\n\n // tjp-related\n // let tjpAddr: IbGibAddr | undefined = undefined;\n\n // const srcIsTjp = data.isTjp && (rel8ns.tjp ?? []).length === 0; // if we only want one tjp\n const srcIsTjp = data.isTjp; // if we want to allow more than one tjp\n if (srcIsTjp) {\n // if the src is tjp, e.g. is the first ibgib after a fork,\n // then srcAddr is the tjpAddr\n const tjpRel8n: string[] = rel8ns.tjp ?? [];\n tjpRel8n.push(srcAddr);\n rel8ns.tjp = tjpRel8n;\n delete data.isTjp;\n }\n\n // dna-related\n let transformDna: IbGib_V1 | null = null;\n if (dna) {\n transformDna = await buildDna(opts);\n const dnaAddr = getIbGibAddr({ ibGib: transformDna });\n rel8ns.dna = linkedRel8ns?.includes(Rel8n.dna) ?\n rel8ns.dna = [dnaAddr] :\n rel8ns.dna = (rel8ns.dna || []).concat(dnaAddr);\n }\n\n // set final ib, data, rel8ns, gib values\n newIbGib.ib = mut8Ib ? mut8Ib : newIbGib.ib;\n newIbGib.rel8ns = rel8ns;\n if (Object.keys(data).length > 0) {\n newIbGib.data = data;\n } else {\n // we've removed the last key in the data object so delete it\n delete newIbGib.data;\n }\n const hasTjp = (rel8ns.tjp?.length ?? 0) > 0;\n newIbGib.gib = await getGib({ ibGib: newIbGib, hasTjp });\n\n // wrap in the result and return\n const result: TransformResult<IbGib_V1> = { newIbGib };\n if (transformDna) { result.dnas = [transformDna]; }\n return result;\n}\n\n\nfunction renameOrRemove(obj: any, info: any, which: 'rename' | 'remove'): any {\n const lc = `[renameOrRemove]`;\n const FORBIDDEN_RENAME_REMOVE_KEYS = ['timestamp'];\n Object.keys(info).forEach(key => {\n if (FORBIDDEN_RENAME_REMOVE_KEYS.includes(key)) {\n throw new Error(`${lc} Cannot rename to ${key}.`);\n }\n if (Object.keys(obj).includes(key)) {\n let infoVal = info[key];\n if (typeof (infoVal) === 'string') {\n // rename\n if (FORBIDDEN_RENAME_REMOVE_KEYS.includes(infoVal)) {\n throw new Error(`${lc} Cannot rename to ${infoVal}.`);\n }\n if (which === 'rename') {\n obj[infoVal] = obj[key];\n }\n delete obj[key];\n } else {\n // recurse\n obj[key] = renameOrRemove(obj[key], infoVal, which);\n }\n } else {\n console.log(`${lc} key to ${which} does not exist`);\n }\n });\n return obj;\n};\n\n/**\n * Patches obj (active mutate, does not copy) with patchObj data. Special keys\n * can rename/remove keys, otherwise is an additive patch.\n *\n * @param obj source obj to patch, possibly is a subobject in a recursive call\n * @param patchInfo data to patch into obj, possibly containing nested objects\n */\nfunction patch(obj: any, patchInfo: any): any {\n Object.keys(patchInfo).forEach(patchKey => {\n // grab the patchVal before updating patchKey\n let patchVal = patchInfo[patchKey];\n let objVal = obj[patchKey];\n if (objVal) {\n if (Array.isArray(patchVal) || Array.isArray(objVal)) {\n // both are arrays, so full replace\n obj[patchKey] = patchVal;\n } else if (typeof (patchVal) === 'object' && typeof (objVal) === 'object') {\n // {a: {b: 2}}, {a: {b: 3, c: 4}}\n // patchKey = 'a';\n // patchVal = {b: 3, c: 4}\n // objVal = {b: 2}\n // recurse\n obj[patchKey] = patch(objVal, patchVal);\n } else {\n // not both objects, so full replace\n obj[patchKey] = patchVal;\n }\n } else {\n // does not exist yet, so set new\n obj[patchKey] = patchVal;\n }\n });\n return obj;\n};\n", "import { getIbGibAddr, } from '../../helper.mjs';\nimport { clone, getTimestamp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1, Rel8n } from '../types.mjs';\nimport { TransformOpts_Rel8, TransformResult, IbGibAddr } from '../../types.mjs';\nimport { IBGIB_DELIMITER, GIB, FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES } from '../constants.mjs';\nimport { buildDna, getGib, isPrimitive } from './transform-helper.mjs';\n/**\n * Original-ish V1 transform behavior.\n *\n * NOTE:\n * This is NOT going to do the plan^gib stuff ATM.\n * Also this does NOT add any identity information ATM.\n */\n/**\n * Relate (and/or unrelate) other ibGib(s), thus mutating it **extrinsically**.\n */\nexport async function rel8(\n opts: TransformOpts_Rel8<IbGib_V1>\n): Promise<TransformResult<IbGib_V1>> {\n const {\n noTimestamp, dna, linkedRel8ns,\n rel8nsToAddByAddr, rel8nsToRemoveByAddr,\n type = 'rel8'\n } = opts;\n let src = opts.src;\n const lc = '[rel8_v1]';\n if (type !== 'rel8') { throw new Error(`${lc} not a rel8 transform.`); }\n if (!opts.type) { opts.type = 'rel8' }\n\n // #region validation\n\n if (type !== 'rel8') { throw new Error(`${lc} not a rel8 transform.`); }\n if (!opts.type) { opts.type = 'rel8' }\n\n if (!src) { throw new Error(`${lc} src required.`); }\n if (!src!.ib) { throw new Error(`${lc} src.ib required.`); }\n if (src!.ib!.includes(IBGIB_DELIMITER)) {\n throw new Error(`${lc} ib can't contain hardcoded delimiter (${IBGIB_DELIMITER}) right now.`);\n }\n if (!src!.gib) { throw new Error(`${lc} src.gib required.`); }\n\n // if (!src.gib || src.gib === GIB) { throw new Error(`${lc} cannot relate to primitive ibGib.`); }\n if (isPrimitive({ ibGib: src })) { throw new Error(`${lc} cannot relate/unrelate primitive ibgib`); }\n\n // if neither add nor remove specified, what are we even doing?\n const isAdding = rel8nsToAddByAddr && Object.keys(rel8nsToAddByAddr!).length > 0;\n const isRemoving = rel8nsToRemoveByAddr && Object.keys(rel8nsToRemoveByAddr!).length > 0;\n if (!(isAdding || isRemoving)) {\n throw new Error(`${lc} gotta provide relations to either add or remove.`);\n }\n\n const srcAddr = getIbGibAddr({ ib: src.ib, gib: src.gib });\n if (opts.srcAddr && srcAddr !== opts.srcAddr) { throw new Error(`${lc} srcAddr from src does not equal opts.srcAddr`); }\n opts.srcAddr = srcAddr;\n\n // validate all ibgib addresses to add/remove\n const fnValidIbGibAddr = (s: string) => {\n // for now, only requiring a single character and trailing delim.\n // i.e. primitive with implied 'gib'\n return s && typeof (s) === 'string' && s.length >= 2 &&\n s.includes('^') && s.split('^')[0].length >= 1;\n };\n Object.keys(rel8nsToAddByAddr || {})\n .map(x => (rel8nsToAddByAddr || {})[x])\n .forEach(rel8ds => {\n if (!(rel8ds && rel8ds.every(rel8d => fnValidIbGibAddr(rel8d)))) {\n throw new Error(`${lc} Invalid rel8n attempt. Must be valid ibGibs. Did you include a delimiter (^)?`);\n }\n });\n Object.keys(rel8nsToRemoveByAddr || {})\n .map(x => (rel8nsToRemoveByAddr || {})[x])\n .forEach(rel8ds => {\n if (!(rel8ds && rel8ds.every(rel8d => fnValidIbGibAddr(rel8d)))) {\n throw new Error(`${lc} Invalid remove rel8n attempt. Must be valid ibGibs. Did you include a delimiter (^)?`);\n }\n });\n\n // #endregion validation\n\n // we want to forget `src` proper very quickly because it may have other\n // non-IbGib properties that are not relevant to our transform.\n let dto: IbGib_V1 = { ib: src.ib, gib: src.gib, };\n if (src.data && Object.keys(src.data).length > 0) { dto.data = src.data; }\n if (src.rel8ns && Object.keys(src.rel8ns).length > 0) { dto.rel8ns = src.rel8ns; }\n src = dto;\n\n const newIbGib = clone(src) as IbGib_V1<IbGibData_V1>;\n\n const data: any = clone(src.data || {});\n if (opts.nCounter || Object.keys(data).includes('n')) {\n if (Object.keys(data).includes('n')) {\n if (Number.isInteger(data.n)) {\n if (data.n >= 0) {\n data.n = data.n + 1;\n } else {\n console.warn(`${lc} data.n is less than 0, which is unexpected. Resetting data.n to 0.`);\n data.n = 0;\n }\n } else {\n throw new Error('cannot increment nCounter because data.n is not a number.');\n }\n } else {\n data.n = 0;\n }\n }\n\n if (!noTimestamp) {\n const date = new Date();\n data.timestamp = getTimestamp(date);\n data.timestampMs = date.getMilliseconds();\n }\n\n const rel8ns: IbGibRel8ns_V1 = clone(src.rel8ns || {});\n Object.keys(rel8nsToAddByAddr || {}).forEach(rel8nName => {\n if (FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES.includes(rel8nName)) {\n throw new Error(`${lc} Cannot manually add relationship: ${rel8nName}.`);\n }\n const existingRel8d = rel8ns[rel8nName] || [];\n const toAddRel8d = rel8nsToAddByAddr![rel8nName];\n const newRel8d = toAddRel8d!.filter(x => !existingRel8d.includes(x));\n rel8ns[rel8nName] = existingRel8d.concat(newRel8d);\n });\n Object.keys(rel8nsToRemoveByAddr || {}).forEach(rel8nName => {\n if (FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES.includes(rel8nName)) {\n throw new Error(`${lc} Cannot manually remove relationship: ${rel8nName}.`);\n }\n const existingRel8d = rel8ns[rel8nName] || [];\n const toRemoveRel8d = rel8nsToRemoveByAddr![rel8nName] || [];\n const prunedRel8d = existingRel8d.filter((x: IbGibAddr) => !toRemoveRel8d!.includes(x));\n if (prunedRel8d.length > 0) {\n rel8ns[rel8nName] = prunedRel8d;\n } else {\n delete rel8ns[rel8nName];\n }\n });\n rel8ns.past = (rel8ns.past || []).concat([srcAddr]);\n (linkedRel8ns || [])\n .filter(linkedRel8nName => Object.keys(rel8ns).includes(linkedRel8nName))\n .filter(linkedRel8nName => (rel8ns[linkedRel8nName] || []).length > 1)\n .forEach(linkedRel8nName => {\n // take the last item only, and put it in an array\n let initialLength = rel8ns[linkedRel8nName]!.length;\n rel8ns[linkedRel8nName] = [rel8ns[linkedRel8nName]![initialLength - 1]];\n });\n\n // rel8ns.past = linkedRel8ns?.includes(Rel8n.past) ?\n // [srcAddr] :\n // (rel8ns.past || []).concat([srcAddr]);\n\n if (data.isTjp) {\n let tjpRel8n: IbGibAddr[] = rel8ns['tjp'] || [];\n tjpRel8n.push(srcAddr);\n rel8ns.tjp = tjpRel8n;\n delete data.isTjp;\n }\n\n newIbGib.data = data;\n newIbGib.rel8ns = rel8ns;\n // newIbGib.gib = await sha256v1(newIbGib, '');\n const hasTjp = (rel8ns.tjp?.length ?? 0) > 0;\n\n let transformDna: IbGib_V1 | null = null;\n if (dna) {\n transformDna = await buildDna(opts);\n const dnaAddr = getIbGibAddr({ ibGib: transformDna });\n rel8ns.dna = linkedRel8ns?.includes(Rel8n.dna) ?\n rel8ns.dna = [dnaAddr] :\n rel8ns.dna = (rel8ns.dna || []).concat(dnaAddr);\n }\n\n newIbGib.gib = await getGib({ ibGib: newIbGib, hasTjp });\n\n const result: TransformResult<IbGib_V1> = { newIbGib };\n if (transformDna) { result.dnas = [transformDna]; }\n return result;\n}\n", "import { clone, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { getIbGibAddr, } from '../helper.mjs';\nimport { getGibInfo } from './transforms/transform-helper.mjs';\nimport { IbGibRel8ns_V1, IbGib_V1 } from \"./types.mjs\";\nimport { GIB, GIB_DELIMITER } from './constants.mjs';\n\n/**\n * Helper function that checks the given `ibGib` to see if it\n * either has a tjp or is a tjp itself.\n *\n * ## notes\n *\n * Only unique ibGibs are meant to have tjps, or rather, if an\n * ibGib timeline is expected to be unique over \"time\", then the\n * tjp is an extremely convenient mechanism that provides a\n * \"name\" for that timeline.\n *\n * Otherwise, if they are not unique, then successive \"different\"\n * timelines cannot be easily referenced by their first unique\n * frame in time, making it much harder to pub/sub updates among\n * other things. (If there are no unique frames, then they are\n * the same ibGib.)\n *\n * ## tjp = temporal junction point\n *\n * I've written elsewhere on this as well. Refer to B2tF2.\n *\n * @returns true if the ibGib has/is a tjp, else false\n */\nexport function hasTjp({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${hasTjp.name}]`;\n\n if (!ibGib) {\n console.warn(`${lc} ibGib falsy. (W: 884178562f5b4f15933ac4d98db74cc6)`);\n return false;\n }\n\n if (ibGib.data?.isTjp || ibGib.rel8ns?.tjp?.length! > 0) {\n return true;\n }\n\n // dna transforms do not have tjp\n const dnaPrimitives = ['fork^gib', 'mut8^gib', 'rel8^gib'];\n if ((ibGib.rel8ns?.ancestor ?? []).some(x => dnaPrimitives.includes(x))) {\n return false;\n }\n\n if (!ibGib.gib) {\n console.warn(`${lc} ibGib.gib falsy. (W: 6400d780822b44d992846f1196509be3)`);\n return false;\n }\n if (ibGib.gib.includes(GIB_DELIMITER)) {\n return true;\n }\n\n if (ibGib.gib === GIB) {\n // primitive\n return false;\n }\n\n // use more expensive getGibInfo call.\n // could possibly just return false at this point, but since gib info\n // would change if we change our standards for gib, this is nicer.\n const gibInfo = getGibInfo({ ibGibAddr: getIbGibAddr({ ibGib }) });\n return gibInfo.tjpGib ? true : false;\n}\n\n/**\n * If you have an ibgib object, it may also contain other properties/functions.\n *\n * This helper function takes the incoming object and returns a copy\n * @param param0\n * @returns\n */\nexport function toDto<TData, TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1>({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): IbGib_V1<TData, TRel8ns> {\n const lc = `[${toDto.name}]`;\n if (!ibGib.ib) { console.warn(`${lc} ibGib.ib is falsy. (W: e60e41c2a1fc48268379d88ce13cb77b)`); }\n if (!ibGib.gib) { console.warn(`${lc} ibGib.gib is falsy. (W: fb3889cbf0684ae4ac51e48f28570377)`); }\n\n let dtoIbGib: IbGib_V1<TData, TRel8ns> = { ib: (ibGib.ib || '').slice() };\n if (ibGib.gib) { dtoIbGib.gib = ibGib.gib.slice(); };\n if (ibGib.data) {\n // we do not clone binaries when creating the dto.\n dtoIbGib.data =\n ibGib.data instanceof Uint8Array ?\n ibGib.data :\n clone(ibGib.data);\n }\n if (ibGib.rel8ns) { dtoIbGib.rel8ns = clone(ibGib.rel8ns); }\n\n return dtoIbGib;\n}\n", "import {\n HEXADECIMAL_HASH_STRING_REGEXP_32, HEXADECIMAL_HASH_STRING_REGEXP_64,\n} from '@ibgib/helper-gib/dist/constants.mjs';\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { Ib, IbGibAddr, } from '../types.mjs';\nimport { IbGibRel8ns_V1, IbGib_V1, } from './types.mjs';\nimport { IBGIB_DELIMITER, GIB, IB, GIB_DELIMITER, } from './constants.mjs';\nimport { isPrimitive, getGib, getGibInfo } from './transforms/transform-helper.mjs';\nimport { hasTjp, toDto } from './v1-helper.mjs';\nimport { getIbAndGib, getIbGibAddr } from '../helper.mjs';\n\nconst logalot = false;\n\n/**\n * validates the ibGib's address (`ib` and `gib` properties) and recalculates\n * the `gib` against the `ibGib.gib`.\n *\n * this validates not only that the punctiliar gib hash for this ibgib record\n * hashes to the same value, but it also checks the internal tjp address and\n * ensures that it is the same tjp gib in the gib field.\n *\n * ## notes\n *\n * * By checking the tjp gib is the same in the address as in the tjp rel8n, we\n * are providing (extremely?) good corroboration that the tjp listed in the\n * address is accurate. However, it may still be theoretically possible to\n * forge an ibgib that both hashes to the punctiliar hash and matches up this\n * tjpAddr.gib. This would be AFAICT quite challenging.\n */\nexport async function validateIbGibIntrinsically({\n ibGib\n}: {\n ibGib: IbGib_V1\n}): Promise<string[] | null> {\n const lc = `[${validateIbGibIntrinsically.name}]`;\n try {\n let errors: string[] = [];\n if (ibGib) {\n const addr = getIbGibAddr({ ibGib });\n errors = validateIbGibAddr({ addr }) ?? [];\n\n if (errors.length > 0) {\n console.error(`${lc} errors found in addr: ${addr}`);\n return errors; // <<<< returns early\n }\n\n // rest of the function assumes correctly formatted ib and gib\n\n // if it's a primitive, the caller knows (or should know!) there are no\n // metadata guarantees.\n if (isPrimitive({ gib: ibGib.gib })) { return null; }\n\n // this validates not only that the punctiliar gib hash for this ibgib record\n // hashes to the same value, but it also checks the internal tjp address and\n // ensures that it is the same tjp gib.\n // not necessary the dto here, but I'm sensitive at this point.\n let gottenGib = await getGib({ ibGib: toDto({ ibGib }), hasTjp: hasTjp({ ibGib }) });\n if (gottenGib !== ibGib.gib) {\n if (ibGib.data?.src && ibGib.data.srcAddr && ibGib.ib === 'rel8') {\n // this is NOT the place to do this, but I'm plodding through trying to think of how to fix it\n // this is what it looks like in data\n // {\n // \"rel8nsToAddByAddr\":{\n // \"comment\":[\"comment 11221^F6B9477984D31FEF5FD25297CA39126A64ADDE2C91C1A2D670CCFE3965DEC4C9.847F0E9A1B2738DC167B32AA9B2D7D9B88B76F21848B1F193E994BB21F90DAEE\"]\n // },\n // \"dna\":true,\n // \"nCounter\":true,\n // \"type\":\"rel8\"\n // }\n delete ibGib.data.src;\n delete ibGib.data.srcAddr;\n gottenGib = await getGib({ ibGib: toDto({ ibGib }), hasTjp: hasTjp({ ibGib }) });\n if (gottenGib !== ibGib.gib) {\n errors.push(`Ibgib invalid intrinsically - gottenGib (${gottenGib}) does not equal ibGib.gib (${ibGib.gib}). (E: 020b71479e944b2198fe436e7e137786)`);\n // } else {\n // debugger;\n }\n } else {\n errors.push(`Ibgib invalid intrinsically - gottenGib (${gottenGib}) does not equal ibGib.gib (${ibGib.gib}). (E: 7416db016878430ca3c5b20697f164ed)`);\n }\n }\n\n return errors.length > 0 ? errors : null;\n } else {\n errors.push(`ibGib is itself falsy. (E: 4fb98caf6ed24ef7b35a19cef56e2d7e)`);\n return errors;\n }\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Naive synchronous validation for ibgib addresses.\n *\n * @returns error string array if validation errors found, else null\n */\nexport function validateIbGibAddr({\n addr,\n delimiter,\n version,\n}: {\n addr: IbGibAddr,\n delimiter?: string,\n version?: string,\n}): string[] | null {\n const lc = `[${validateIbGibAddr.name}]`;\n try {\n let errors: string[] = [];\n if (version) { console.warn(`${lc} version not implemented yet. Ignoring. (W: 2d19db16ec0c4766b5d35248787671f3)`); }\n\n // validate as a whole\n if (!addr) {\n errors.push(`addr required. (E: e9a54041aa0b41c1bb2324d9d2d42c7f)`);\n return errors;\n }\n delimiter = delimiter || IBGIB_DELIMITER;\n if (!addr.includes(delimiter)) { errors.push(`No delimiter (${delimiter}) found. (E: 05e28dcb70ff44019edc53ed508bd1e8)`); }\n if (addr.startsWith(delimiter)) { errors.push(`addr starts with delim. (E: d29f808c5a47452f9bb3ea684694c6eb)`); }\n\n // validate pieces...\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr, delimiter });\n\n // ...ib\n const resValidateIb = validateIb({ ib, ibGibAddrDelimiter: delimiter, version });\n if (resValidateIb) { errors = errors.concat(resValidateIb); }\n\n // ...gib\n const resValidateGib = validateGib({ gib, ibGibAddrDelimiter: delimiter, version });\n if (resValidateGib) { errors = errors.concat(resValidateGib); }\n\n if (errors.length > 0) {\n if (logalot) { console.log(`${lc} errors.length > 0. errors: ${errors.join('|')} (I: 9c18f993e138f15613e4c6a340d41722)`); }\n }\n\n // we're done\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Naive validation of ib.\n *\n * @returns errors array if found, else null\n */\nexport function validateIb({\n ib,\n ibGibAddrDelimiter,\n version,\n}: {\n ib: Ib,\n ibGibAddrDelimiter?: string,\n version?: string,\n}): string[] | null {\n const lc = `[${validateIb.name}]`;\n try {\n const errors: string[] = [];\n if (version) { console.warn(`${lc} version not implemented yet. Ignoring. (W: 71228ba4ed994aaa8149910e295ab087)`); }\n\n if (!ib) {\n errors.push(`ib required. (E: a76d06c7b9c24db3a731a91dbe46acd5)`);\n return errors;\n }\n\n if (ib === IB) { return null; }\n\n ibGibAddrDelimiter = ibGibAddrDelimiter || IBGIB_DELIMITER;\n if (ib.includes(ibGibAddrDelimiter)) { errors.push(`ib contains ibGibAddrDelimiter (${ibGibAddrDelimiter}) (E: 09e61b46c3e84874bc02b6918f1f2c39)`); }\n\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * validates a `gib` of some ibGib/ibGibAddr.\n *\n * @returns array of validation error strings (if any) or null\n */\nexport function validateGib({\n gib,\n gibDelimiter,\n ibGibAddrDelimiter,\n version,\n}: {\n /**\n * gib to validate.\n *\n * ## notes\n *\n * If the gib has a tjp embedded in it (i.e. the associated ibgib has a\n * tjp), then this will call validation on that tjpGib recursively.\n */\n gib: Ib,\n /**\n * This is a delimiter used with tjpGibs.\n *\n * atow this is a dot (`'.'`).\n *\n * ## notes\n *\n * THIS IS NOT THE SAME THING AS THE `ibGibAddrDelimiter`!\n */\n gibDelimiter?: string,\n /**\n * This is a delimiter used with the entire ibGibAddr.\n *\n * atow this is a caret (`'^'`).\n *\n * ## notes\n *\n * THIS IS NOT THE SAME THING AS THE `gibDelimiter`!\n */\n ibGibAddrDelimiter?: string,\n /**\n * Ignored atow, but in the future, probably will be used.\n * May end up being an IbGibAddr but who knows.\n */\n version?: string,\n}): string[] | null {\n const lc = `[${validateGib.name}]`;\n try {\n const errors: string[] = [];\n if (version) { console.warn(`${lc} version not implemented yet. Ignoring. (E: 90ced1db69774702b92acb261bdaee23)`); }\n\n if (!gib) {\n errors.push(`gib required. (E: e217de4035b04086827199f4bace189c)`);\n return errors;\n }\n\n ibGibAddrDelimiter = ibGibAddrDelimiter || IBGIB_DELIMITER;\n /** Need to move this to ts-gib */\n const INVALID_GIB_CHARS = [ibGibAddrDelimiter];\n const invalidCharsFound: string[] = [];\n INVALID_GIB_CHARS.forEach(invalidChar => {\n if (gib.includes(invalidChar)) { invalidCharsFound.push(invalidChar); }\n });\n if (invalidCharsFound.length > 0) {\n errors.push(`gib (${gib}}) contains invalid characters: (${JSON.stringify(invalidCharsFound.join(','))}) (E: 1e584258d9e049ba9ce7e516f3ab97f1)`);\n }\n\n // punctiliar = point, i.e., a single point in the universe, either a\n // single point in time in a tjp ibgib's timeline, or a single point in\n // space that lives outside of time (has no tjp thus no timeline).\n //\n // So if we've gotten here in code, then our gib is truthy and doesn't\n // contain invalid characters.\n\n const { punctiliarHash, tjpGib, isPrimitive } =\n getGibInfo({ gib, gibDelimiter: gibDelimiter || GIB_DELIMITER });\n\n // automatically valid if it's a primitive, as the caller should expect\n // no cryptographical guarantees\n if (isPrimitive) { return null; }\n\n // Gib is not primitive so must have at least the punctiliar hash.\n if (!punctiliarHash) { throw new Error(`${lc} punctiliarHash is falsy on a non-primitive gib. (E: 72835394918241bdb2632bf0510bdae5)`); }\n const punctiliarHashIs_32 = punctiliarHash!.match(HEXADECIMAL_HASH_STRING_REGEXP_32);\n const punctiliarHashIs_64 = punctiliarHash!.match(HEXADECIMAL_HASH_STRING_REGEXP_64);\n if (!punctiliarHashIs_32 && !punctiliarHashIs_64) {\n errors.push('gib punctiliar hash is neither a 32- or 64-char hash string. (E: d47ff6d6e14b4c02a62107090c8dad39)');\n }\n\n if (tjpGib) {\n // if it is an ibgib in a timeline, that timeline has a tjp and this\n // gib has a tjpGib component. So we must recursively validate the\n // tjpGib\n const tjpGibValidationErrors = validateGib({ gib: tjpGib });\n if ((tjpGibValidationErrors ?? []).length > 0) {\n errors.push(`tjpGib has errors (E: d6b79228d4a64c0b967cdb0efcea4d0d). tjpGibValidationErrors: ${tjpGibValidationErrors!.join('. ')}`);\n }\n }\n\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * verifies that\n * @param param0\n * @returns\n */\nexport function validateRel8nsIntrinsically({\n rel8ns,\n}: {\n rel8ns: IbGibRel8ns_V1,\n}): string[] | null {\n const lc = `[${validateRel8nsIntrinsically.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 62b4722599798dd8ab95fcebf42c0e23)`); }\n\n let errors: string[] = [];\n\n const rel8nNames = Object.keys(rel8ns);\n for (let i = 0; i < rel8nNames.length; i++) {\n // all rel8nNames/keys are strings\n const rel8nName = Object.keys(rel8ns)[i];\n if (typeof rel8nName !== 'string') {\n errors.push(`non-string rel8nName found. all keys of rel8ns must be of type string. (E: 3b2e4582b638421681951f5475c85178)`)\n }\n\n // all values are ibgib addr arrays\n const addrs = rel8ns[rel8nName] ?? [];\n for (let j = 0; j < addrs.length; j++) {\n const addr = addrs[j];\n const addrErrors = validateIbGibAddr({ addr }) ?? [];\n if (addrErrors.length > 0) {\n errors.push(`invalid addr found for rel8nName (${rel8nName}). addr errors: ${addrErrors.join('|')} (E: 56809a746c4f462db426e90395b80364)`);\n }\n }\n }\n return errors.length > 0 ? errors : null;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { fork } from './transforms/fork.mjs';\nimport { mut8 } from './transforms/mut8.mjs';\nimport { rel8 } from './transforms/rel8.mjs';\nimport { Ib, IbGib, IbGibRel8ns, TransformResult, TemporalJunctionPointOptions } from '../types.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from './types.mjs';\nimport { IB, GIB, ROOT, IB_REGEXP_DEFAULT, FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES } from './constants.mjs';\nimport { validateIb } from './validate-helper.mjs';\nimport { getGib } from './transforms/transform-helper.mjs';\n\nconst logalot = false;\n\nexport class Factory_V1 {\n static root() {\n return Factory_V1.primitive({ ib: IB });\n }\n\n /**\n * Returns an ibGib primitive with the given `ib`, e.g. \"{ib: '7', gib: 'gib'}\".\n *\n * @returns a single primitive ibGib\n */\n static primitive({\n ib\n }: {\n ib: Ib\n }): IbGib_V1 {\n return { ib, gib: GIB };\n }\n\n /**\n * generates multiple primitive ibgibs from the given `ibs` array.\n * @returns array of generated ibgibs.\n */\n static primitives({\n ibs\n }: {\n ibs: Ib[]\n }): IbGib_V1[] {\n return ibs.map(ib => Factory_V1.primitive({ ib }));\n }\n\n /**\n * Takes the incoming `parentIbGib` and forks it. Then applies the\n * `data` and/or `rel8ns` if any, depending on the other config params.\n *\n * @returns The entire transform result object that includes the newly produced ibGib as well as any derivative/intermediate ibgibs.\n */\n static async firstGen<TData = any>({\n ib = IB,\n parentIbGib = Factory_V1.root(),\n data,\n rel8ns,\n dna,\n tjp,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n squash,\n }: {\n ib: Ib,\n parentIbGib: IbGib,\n data?: TData,\n rel8ns?: IbGibRel8ns,\n dna?: boolean,\n tjp?: TemporalJunctionPointOptions;\n linkedRel8ns?: string[],\n /**\n * If true, no timestamp will be\n */\n noTimestamp?: boolean,\n /**\n * if true, data.n will be set to 0 on the first frame, and 1 on the\n * second.\n */\n nCounter?: boolean,\n /**\n * ONLY USED IF {@link dna} IS FALSY.\n *\n * If {@link dna} is falsy and this is true, then the resulting 1st gen\n * ibgib will be squashed into a single frame, even if both mut8 and\n * rel8 transforms are executed.\n *\n * ## intent / driving use case\n *\n * We are working on the new, production-quality v1 sync saga and we\n * want the saga ibgib to be one frame per participant (Alice, Bob).\n * So Alice creates one frame, then Bob evolves 1 frame, etc. No dna\n * is required, because this is not meant to be merged at a later time.\n *\n * So the use case is when you don't need dna and you want a single\n * frame.\n */\n squash?: boolean,\n }): Promise<TransformResult<IbGib_V1>> {\n const lc = `[${Factory_V1.name}][${Factory_V1.firstGen.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b7152fbd94382516d9f7c591bcf4c326)`); }\n\n if (dna && squash) { throw new Error(`both dna and squash cannot be true. Squash requires that no dna exist. (E: abfc58b4a4c8654924aa5428d0831826)`); }\n\n /** * Multiple transform steps will create multiple results. */\n const interimResults: TransformResult<IbGib_V1>[] = [];\n let src: IbGib_V1 = parentIbGib || ROOT;\n let resFork = await fork({\n src,\n destIb: ib,\n tjp,\n dna,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n });\n interimResults.push(resFork);\n src = resFork.newIbGib;\n\n if (data) {\n let resMut8 = await mut8({\n src,\n dataToAddOrPatch: data,\n dna,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n });\n interimResults.push(resMut8);\n src = resMut8.newIbGib;\n };\n\n if (rel8ns) {\n let resRel8 = await rel8({\n src,\n rel8nsToAddByAddr: rel8ns,\n dna,\n linkedRel8ns,\n noTimestamp,\n nCounter,\n });\n interimResults.push(resRel8);\n // src = resRel8.newIbGib; // not needed because not used (this is the last step)\n }\n\n if (interimResults.length > 1) {\n const newIbGib = interimResults.slice(interimResults.length - 1)[0].newIbGib;\n const resultWithIntermediates = {\n newIbGib,\n /**\n * all the interResults except the last one go in the intermediate ibGibs\n */\n intermediateIbGibs: interimResults.slice(0, interimResults.length - 1).map(x => x.newIbGib),\n } as TransformResult<IbGib_V1>;\n\n if (dna) {\n if (squash) { (`${lc} (E: 62c595422e21ad8ce8eae658976fd826)`) }\n\n // combine all of the interim dnas\n let dnas: IbGib_V1[] = [];\n interimResults.forEach(res => { dnas = dnas.concat(res.dnas!); });\n resultWithIntermediates.dnas = dnas;\n\n return resultWithIntermediates;\n } else if (squash) {\n // manually remove past and change the tjp, if it exists, reset n\n if (!newIbGib.rel8ns) { throw new Error(`(UNEXPECTED) newIbGib.rel8ns is falsy? (E: 6b09e8057fc5b00c6cfd13be60e97f26)`); }\n\n delete newIbGib.rel8ns.past;\n\n if (newIbGib.rel8ns.tjp) {\n delete newIbGib.rel8ns.tjp;\n newIbGib.data ??= {};\n newIbGib.data.isTjp = true;\n }\n\n if (nCounter) {\n newIbGib.data ??= {};\n newIbGib.data.n = 0;\n }\n\n // recalculate the gib\n newIbGib.gib = await getGib({ ibGib: newIbGib });\n\n const resultSquashed: TransformResult<IbGib_V1> = { newIbGib };\n\n return resultSquashed;\n } else {\n // no dna and no squash\n return resultWithIntermediates;\n }\n } else if (interimResults.length === 1) {\n // for some reason the caller just used this as a fork.\n return interimResults[0];\n } else {\n throw new Error(`(UNEXPECTED) interimResults.length is not 1 and not greater than 1? 0? But we had to fork? (E: a256c88c56916a46a888796f76ef4826)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Generate an ibgib datum that has no dna and no timeline.\n * It's a one-off ibgib.\n *\n * This is similar to {@link Factory_V1.constant}, but this is not\n * necessarily deterministic. It can have a timestamp and/or uuid, though it\n * does not have dna, nCounter, or a tjp.\n *\n * ## validation\n *\n * * validates the given `ib` against `ibRegExpPattern` or default regexp.\n * * validates that rel8ns doesn't include default forbidden rel8n names or\n * atow `'tjp'`.\n *\n * ## intent\n *\n * Stones are useful for one-off ibgibs that are not part of a timeline, but\n * which still should have a timestamp and/or uuid.\n *\n * @see {@link Factory_V1.constant}\n */\n static async stone<\n TData extends IbGibData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n >({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n noTimestamp,\n uuid,\n }: {\n parentPrimitiveIb: Ib,\n ib: Ib,\n /**\n * for checking the stone's generated ib\n */\n ibRegExpPattern?: string,\n data?: TData,\n rel8ns?: TRel8ns,\n noTimestamp?: boolean,\n /**\n * If true, will generate a uuid for the stone. If falsy, will not.\n */\n uuid?: boolean,\n }): Promise<IbGib_V1<TData, TRel8ns>> {\n const lc = `[${Factory_V1.name}][${Factory_V1.stone.name}]`;\n try {\n // validation\n // parentPrimitiveIb\n if (!parentPrimitiveIb) { throw new Error(`parentPrimitiveIb required. (E: genuuid)`); }\n if (validateIb({ ib: parentPrimitiveIb }) !== null) { throw new Error(`Invalid parentPrimitiveIb: ${parentPrimitiveIb}. (E: genuuid)`); }\n\n // ib\n if (!ib) { throw new Error(`ib required. (E: genuuid)`); }\n const regExp = ibRegExpPattern ? new RegExp(ibRegExpPattern) : IB_REGEXP_DEFAULT;\n if (!ib.match(regExp)) { throw new Error(`invalid ib. does not match regexp (${regExp}) (E: genuuid)`); }\n\n // rel8ns\n const incomingRel8nNames = Object.keys(rel8ns ?? {});\n const forbiddenRel8nNames = [...FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES, 'tjp'];\n const rel8nsIsInvalid = incomingRel8nNames.some(x => {\n // we don't want constants trying to look like they have/are descendants/tjps/etc.\n return forbiddenRel8nNames.includes(x);\n });\n if (rel8nsIsInvalid) { throw new Error(`Invalid rel8ns. forbiddenRel8nNames: ${forbiddenRel8nNames}. rel8ns keys: ${Object.keys(rel8ns ?? {})}. (E: genuuid)`); }\n\n\n // create the stone by using the firstGen factory. Then we'll pare\n // off what we don't need.\n const resFirstGen = await Factory_V1.firstGen({\n ib,\n parentIbGib: Factory_V1.primitive({ ib: parentPrimitiveIb }),\n data,\n rel8ns,\n dna: false,\n noTimestamp,\n nCounter: false,\n });\n const stoneIbGib = resFirstGen.newIbGib as IbGib_V1<TData, TRel8ns>;\n if (uuid) {\n if (!stoneIbGib.data) { stoneIbGib.data = {} as TData; }\n stoneIbGib.data.uuid = await getUUID();\n }\n\n // remove any extraneous stuff\n if (stoneIbGib.rel8ns?.past) { delete stoneIbGib.rel8ns.past; }\n if (stoneIbGib.rel8ns?.tjp) { delete stoneIbGib.rel8ns.tjp; }\n\n // recalculate the gib hash\n stoneIbGib.gib = await getGib({\n ibGib: {\n ib: stoneIbGib.ib,\n data: stoneIbGib.data,\n rel8ns: stoneIbGib.rel8ns,\n },\n hasTjp: false,\n });\n\n return stoneIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Generate a deterministic ibgib datum that has no dna and no timeline.\n * It's a one-off ibgib.\n *\n * Because this is supposed to create and re-create deterministically the equivalent\n * of a non-primitive ibgib \"constant\", this function creates a single ibgib with...\n * * one ancestor\n * * no past, dna, or tjp rel8ns\n * * no tjp timestamp or uuid\n * * no nCounter\n *\n * This is similar to {@link Factory_V1.stone}, but with guaranteed no\n * timestamp or uuid (unless incoming {@link data} contains a uuid).\n *\n * @see {@link Factory_V1.stone}\n *\n * ## intent\n *\n * I want to be able to create deterministic ibGibs that I can reference at\n * runtime, similar to an ibgib primitive (e.g. \"root^gib\"), but with the\n * integrity of the `gib` hash. This way, I can reference a deterministic ibgib\n * from code at compile time, and at runtime this will have a corresponding\n * ibgib datum with gib-hashed integrity.\n *\n * ## example\n *\n * I want to create a \"hard-coded\" schema ibgib that I rel8 to some protocol\n * ibgib. So I'll create the data here, which lives in source control in a text file,\n * and then I'll render that as an ibgib that verifies integrity. If I as a coder change\n * it at all, then the `gib` of course will be different.\n */\n static async constant<\n TData extends IbGibData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n >({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n }: {\n parentPrimitiveIb: Ib,\n ib: Ib,\n /**\n * for checking the constant's generated ib\n */\n ibRegExpPattern?: string,\n data?: TData,\n rel8ns?: TRel8ns,\n }): Promise<IbGib_V1<TData, TRel8ns>> {\n const lc = `[${Factory_V1.name}][${Factory_V1.constant.name}]`;\n try {\n const constantIbGib = await Factory_V1.stone({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n noTimestamp: true,\n uuid: false,\n });\n return constantIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n}\n", "/**\n * @module core-constants\n *\n * # IMPORTANT!\n *\n * In order to be able to actually use this in an ionic-gib-like clone front end,\n * I want to be sure to include all of these. So I can't remove/comment it out here\n * without putting it _somewhere_. For example, the very first import atow is a\n * reference to @capacitor/filesystem. This should not go in this package (core-gib)\n * so I'm going to create another lib specific to ionic/capacitor and put it there\n * **before** removing it from/commenting it out in this file.\n *\n * # about this file\n *\n * I'm copying this lump sum from ionic-gib and am breaking it out slowly into\n * other more specific constant files. When a constant is moved into one of\n * those sub files, then I will remove it from this file.\n *\n * Ultimately, this should only contain global constants like the logalot\n * and timer settings.\n */\n\nimport { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\n\n/**\n * Naive selective logging/tracing mechanism.\n *\n * I manually switch this in individual files as needed while\n * developing/troubleshooting. I can change it here to turn on extremely verbose\n * logging application wide (and turn off individual files).\n */\nexport const GLOBAL_LOG_A_LOT: boolean | number = false;\n\n/**\n * Used in console.timeLog() calls.\n */\nexport const GLOBAL_TIMER_NAME = '[core^gib timer]';\n\n\n// export const UUID_REGEXP = /^[a-zA-Z0-9_\\-.]{1,256}$/;\n\n/**\n * regular expression for a classname.\n *\n * Used in witnesses atm.\n */\nexport const CLASSNAME_REGEXP = /^[a-zA-Z0-9_]{1,255}$/;\n\n/**\n * Much restricted list of chars in english.\n *\n * ## intent\n *\n * When sanitizing input.\n */\nexport const SAFE_SPECIAL_CHARS = `.'\",!?-`;\n\nexport const IB_MAX_LENGTH_DEFAULT = 155;\n\n/**\n * Defaults to word characters, space, tab, hyphen, and other\n * non-slash (path navigating) chars.\n *\n * Does not allow new lines or other whitespace, only tabs and spaces.\n *\n * ## atow\n *\n * `^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`\n */\nexport const IB_REGEXP_DEFAULT = new RegExp(`^[\\\\w\\\\t\\\\-|=+.&%\\$#@!~\\` \\\\[\\\\]\\\\(\\\\)\\\\{\\\\}]{1,${IB_MAX_LENGTH_DEFAULT}}$`);\n\n/**\n * Ionicons const \"enum\"\n */\nexport const IONICONS = [\n 'add',\n 'add-circle',\n 'alert',\n 'alert-circle',\n 'add',\n 'airplane',\n 'alarm',\n 'albums',\n 'alert',\n 'alert-circle',\n 'american-football',\n 'analytics',\n 'aperture',\n 'apps',\n 'archive',\n 'arrow-back',\n 'arrow-back-circle',\n 'arrow-down',\n 'arrow-down-circle',\n 'arrow-forward',\n 'arrow-forward-circle',\n 'arrow-redo',\n 'arrow-redo-circle',\n 'arrow-undo',\n 'arrow-undo-circle',\n 'arrow-up',\n 'arrow-up-circle',\n 'at',\n 'at-circle',\n 'attach',\n 'backspace',\n 'bandage',\n 'bar-chart',\n 'barbell',\n 'barcode',\n 'baseball',\n 'basket',\n 'basketball',\n 'battery-charging',\n 'battery-dead',\n 'battery-full',\n 'battery-half',\n 'beaker',\n 'bed',\n 'beer',\n 'bicycle',\n 'bluetooth',\n 'boat',\n 'body',\n 'bonfire',\n 'book',\n 'bookmark',\n 'bookmarks',\n 'briefcase',\n 'browsers',\n 'brush',\n 'bug',\n 'build',\n 'bulb',\n 'bus',\n 'business',\n 'cafe',\n 'calculator',\n 'calendar',\n 'call',\n 'camera',\n 'camera-reverse',\n 'car',\n 'car-sport',\n 'card',\n 'caret-back',\n 'caret-back-circle',\n 'caret-down',\n 'caret-down-circle',\n 'caret-forward',\n 'caret-forward-circle',\n 'caret-up',\n 'caret-up-circle',\n 'cart',\n 'cash',\n 'cellular',\n 'chatbox',\n 'chatbox-ellipses',\n 'chatbubble',\n 'chatbubble-ellipses',\n 'chatbubbles',\n 'checkbox',\n 'checkmark',\n 'checkmark-circle',\n 'checkmark-done',\n 'checkmark-done-circle',\n 'chevron-back',\n 'chevron-back-circle',\n 'chevron-down',\n 'chevron-down-circle',\n 'chevron-forward',\n 'chevron-forward-circle',\n 'chevron-up',\n 'chevron-up-circle',\n 'clipboard',\n 'close',\n 'close-circle',\n 'cloud',\n 'cloud-circle',\n 'cloud-done',\n 'cloud-download',\n 'cloud-offline',\n 'cloud-upload',\n 'cloudy',\n 'cloudy-night',\n 'code',\n 'code-download',\n 'code-slash',\n 'code-working',\n 'cog',\n 'color-fill',\n 'color-filter',\n 'color-palette',\n 'color-wand',\n 'compass',\n 'construct',\n 'contract',\n 'contrast',\n 'copy',\n 'create',\n 'crop',\n 'cube',\n 'cut',\n 'desktop',\n 'disc',\n 'document',\n 'document-attach',\n 'document-text',\n 'documents',\n 'download',\n 'duplicate',\n 'ear',\n 'earth',\n 'easel',\n 'egg',\n 'ellipse',\n 'ellipsis-horizontal',\n 'ellipsis-horizontal-circle',\n 'ellipsis-vertical',\n 'ellipsis-vertical-circle',\n 'enter',\n 'exit',\n 'expand',\n 'eye',\n 'eye-off',\n 'eyedrop',\n 'fast-food',\n 'female',\n 'file-tray',\n 'file-tray-full',\n 'file-tray-stacked',\n 'film',\n 'filter',\n 'finger-print',\n 'fitness',\n 'flag',\n 'flame',\n 'flash',\n 'flash-off',\n 'flashlight',\n 'flask',\n 'flower',\n 'folder',\n 'folder-open',\n 'football',\n 'funnel',\n 'game-controller',\n 'gift',\n 'git-branch',\n 'git-commit',\n 'git-compare',\n 'git-merge',\n 'git-network',\n 'git-pull-request',\n 'glasses',\n 'globe',\n 'golf',\n 'grid',\n 'hammer',\n 'hand-left',\n 'hand-right',\n 'happy',\n 'hardware-chip',\n 'headset',\n 'heart',\n 'heart-circle',\n 'heart-dislike',\n 'heart-dislike-circle',\n 'heart-half',\n 'help',\n 'help-buoy',\n 'help-circle',\n 'home',\n 'hourglass',\n 'ice-cream',\n 'image',\n 'images',\n 'infinite',\n 'information',\n 'information-circle',\n 'journal',\n 'key',\n 'keypad',\n 'language',\n 'laptop',\n 'layers',\n 'leaf',\n 'library',\n 'link',\n 'list',\n 'list-circle',\n 'locate',\n 'location',\n 'lock-closed',\n 'lock-open',\n 'log-in',\n 'magnet',\n 'mail',\n 'mail-open',\n 'mail-unread',\n 'male',\n 'male-female',\n 'man',\n 'map',\n 'medal',\n 'medical',\n 'medkit',\n 'megaphone',\n 'menu',\n 'mic',\n 'mic-circle',\n 'mic-off',\n 'mic-off-circle',\n 'moon',\n 'move',\n 'musical-note',\n 'musical-notes',\n 'navigate',\n 'navigate-circle',\n 'newspaper',\n 'notifications',\n 'notifications-circle',\n 'notifications-off',\n 'notifications-off-circle',\n 'nuclear',\n 'nutrition',\n 'open',\n 'options',\n 'paper-plane',\n 'partly-sunny',\n 'pause',\n 'pause-circle',\n 'paw',\n 'pencil',\n 'people',\n 'people-circle',\n 'person',\n 'person-add',\n 'person-circle',\n 'person-remove',\n 'phone-landscape',\n 'phone-portrait',\n 'pie-chart',\n 'pin',\n 'pint',\n 'pizza',\n 'planet',\n 'play',\n 'play-back',\n 'play-back-circle',\n 'play-circle',\n 'play-forward',\n 'play-forward-circle',\n 'play-skip-back',\n 'play-skip-back-circle',\n 'play-skip-forward',\n 'play-skip-forward-circle',\n 'podium',\n 'power',\n 'pricetag',\n 'pricetags',\n 'print',\n 'pulse',\n 'push',\n 'qr-code',\n 'radio',\n 'radio-button-off',\n 'radio-button-on',\n 'rainy',\n 'reader',\n 'receipt',\n 'recording',\n 'refresh',\n 'refresh-circle',\n 'reload',\n 'reload-circle',\n 'remove',\n 'remove-circle',\n 'reorder-four',\n 'reorder-three',\n 'reorder-two',\n 'repeat',\n 'resize',\n 'restaurant',\n 'return-down-back',\n 'return-down-forward',\n 'return-up-back',\n 'return-up-forward',\n 'ribbon',\n 'rocket',\n 'rose',\n 'sad',\n 'save',\n 'scan',\n 'scan-circle',\n 'school',\n 'search',\n 'search-circle',\n 'send',\n 'server',\n 'settings',\n 'shapes',\n 'share',\n 'share-social',\n 'shield',\n 'shield-checkmark',\n 'shirt',\n 'shuffle',\n 'skull',\n 'snow',\n 'speedometer',\n 'square',\n 'star',\n 'star-half',\n 'stats-chart',\n 'stop',\n 'stop-circle',\n 'stopwatch',\n 'subway',\n 'sunny',\n 'swap-horizontal',\n 'swap-vertical',\n 'sync',\n 'sync-circle',\n 'tablet-landscape',\n 'tablet-portrait',\n 'tennisball',\n 'terminal',\n 'text',\n 'thermometer',\n 'thumbs-down',\n 'thumbs-up',\n 'thunderstorm',\n 'time',\n 'timer',\n 'today',\n 'toggle',\n 'trail-sign',\n 'train',\n 'transgender',\n 'trash',\n 'trash-bin',\n 'trending-down',\n 'trending-up',\n 'triangle',\n 'trophy',\n 'tv',\n 'umbrella',\n 'videocam',\n 'volume-high',\n 'volume-low',\n 'volume-medium',\n 'volume-mute',\n 'volume-off',\n 'walk',\n 'wallet',\n 'warning',\n 'watch',\n 'water',\n 'wifi',\n 'wine',\n 'woman',\n];\n\n// #region other robbot related\n\n/**\n * Robbot.data.name regexp\n */\nexport const ROBBOT_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\nexport const ROBBOT_PREFIX_SUFFIX_REGEXP = /^[a-zA-Z0-9_\\-.\\s\uD83D\uDC40\uD83E\uDD16:;&]{1,64}$/;\nexport const ROBBOT_PREFIX_SUFFIX_REGEXP_DESC =\n `0 to 64 alphanumerics, spaces, select special characters and emojis.`;\n\n// #endregion other robbot related\n\n// #region gestures\n\nexport const GESTURE_DOUBLE_CLICK_THRESHOLD_MS = 500;\n/**\n * If a gesture's move threshold is less than this, then it can still be\n * considered a single punctiliar click. Otherwise, it's a move event.\n *\n * IOW, a click gesture only is considered a \"click\" if the onMove is triggered\n * less than this many times. If onMove is detected more than this many times,\n * then a move gesture will be triggered.\n */\nexport const GESTURE_CLICK_TOLERANCE_ONMOVE_THRESHOLD_COUNT = 5;\n\n// #endregion gestures\n\nexport const SIMPLE_CONFIG_KEY_APP_VISIBLE = 'appBarVisible';\nexport const SIMPLE_CONFIG_KEY_APP_SELECTED = 'appBarSelectedApp';\nexport const SIMPLE_CONFIG_KEY_ROBBOT_VISIBLE = 'robbotBarVisible';\nexport const SIMPLE_CONFIG_KEY_ROBBOT_SELECTED_ADDR = 'robbotBarSelectedAddr';\n\n// #region app\n\nexport const DEFAULT_APP_ICON = 'apps-outline';\n\n// #endregion app\n\nexport const YOUTUBE_LINK_REG_EXP = /^https:\\/\\/youtu\\.be\\/\\w+$/;\n\nexport const WEB_1_PATHS = ['welcome', 'about-us', 'your-data'];\n", "// #region from common/types/legacy.ts\n\n// todo: clean up legacy get/put functions\n// I started ionic-gib without a clear architectural design, so this is \"legacy\"\n// with respect to that. I had several functions that used these types, and I\n// left them as-is at the time. after this refactor, this needs to be cleaned\n// up. Perhaps this goes in capacitor-gib even?\n\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';\n\nexport interface FileResult {\n success?: boolean;\n /**\n * If errored, this will contain the errorMsg.\n */\n errorMsg?: string;\n /**\n * True if failed due to timing out.\n */\n timedOut?: boolean;\n}\n\n/**\n * Options for retrieving data from the file system.\n */\nexport interface GetIbGibOpts {\n /**\n * If getting ibGib object, this is its address.\n */\n addr?: IbGibAddr;\n /**\n * If getting multiple ibGibs, use this array of addrs.\n */\n addrs?: IbGibAddr[];\n /**\n * Are we looking for a DNA ibgib?\n */\n isDna?: boolean;\n /**\n * space from which to get the ibgib\n *\n * @default localUserSpace\n */\n space?: IbGibSpaceAny,\n /**\n * If supplied, first acquires the lock with this scope on the\n * given `space` (which defaults to localUserSpace).\n */\n lockScope?: string,\n /**\n * Cancels if can't acquire lock after approximately this time.\n */\n lockTimeoutMs?: number,\n /**\n * If true, will not get from cache and will force retrieval from the real\n * bucket. In Ionic space, this means will look in ionic storage proper.\n */\n force?: boolean;\n}\n\n/**\n * Result for retrieving an ibGib from the file system.\n */\nexport interface GetIbGibResult extends FileResult {\n /**\n * ibGibs if retrieving a \"regular\" ibGib.\n *\n * This is used when you're not getting a pic, e.g.\n */\n ibGibs?: IbGib_V1[];\n /**\n * This is used when you're getting a pic's binary content.\n */\n // binData?: any;\n /**\n * access to raw result ibgib that caller must cast to the correct shape.\n */\n rawResultIbGib?: IbGib_V1;\n}\n\nexport interface PutIbGibOpts {\n /**\n * ibGib to put.\n *\n * If you only want to do just one, use this param. Otherwise, use the\n * `ibGibs` array param.\n */\n ibGib?: IbGib_V1;\n /**\n * ibGibs to put in the space.\n *\n * If you want to put more than one ibGib, use this param. If you only\n * want to put a single ibGib, you could also use the `ibGib` param.\n */\n ibGibs?: IbGib_V1[];\n /**\n * if true, will store this data in the bin folder with its hash.\n */\n // binData?: string;\n /**\n * If true, will store in a different folder.\n */\n isDna?: boolean;\n /**\n * extension to store the bindata with.\n */\n // binExt?: string;\n /**\n * If true, will replace an existing ibGib file\n */\n force?: boolean;\n /**\n * space into which we shall put the ibgib.\n *\n * @default localCurrentSpace\n */\n space?: IbGibSpaceAny,\n}\n\n/**\n * Result for putting ibgib.\n */\nexport interface PutIbGibResult extends FileResult {\n binHash?: string;\n}\n\nexport interface DeleteIbGibOpts extends GetIbGibOpts { }\nexport interface DeleteIbGibResult extends FileResult { }\n\n// #endregion from common/types/legacy.ts\n\n/**\n * Special ibgib types, used for metadata within a space.\n *\n * Unsure where to place this in core-gib...\n *\n * ## notes\n *\n * * 10/2023\n * * I'm changing this to also be unioned with 'string' because I am working\n * on ibgib app and I need to consume the create special ibgib. so this\n * should be extensible per use case in consuming apps.\n */\nexport type SpecialIbGibType =\n \"tags\" | \"aliases\" | \"roots\" |\n \"outerspaces\" | \"secrets\" |\n \"encryptions\" | \"autosyncs\" | \"robbots\" | \"apps\" | \"history\" |\n string;\n/**\n * Special ibgib types, used for metadata within a space.\n *\n * Unsure where to place this...\n *\n * @see {@link SPECIAL_IBGIB_TYPE_REGEXP}\n */\nexport const SpecialIbGibType = {\n /** indexes all tag ibgibs within a space */\n tags: \"tags\" as SpecialIbGibType,\n /** indexes all aliases within a space */\n aliases: \"aliases\" as SpecialIbGibType,\n /** indexes all root ibgibs within a space */\n roots: \"roots\" as SpecialIbGibType,\n /** indexes all outerspace ibgibs, including sync spaces, within a space */\n outerspaces: \"outerspaces\" as SpecialIbGibType,\n /** indexes all secret ibgibs within a space */\n secrets: \"secrets\" as SpecialIbGibType,\n /** indexes all encryption setting ibgibs within a space */\n encryptions: \"encryptions\" as SpecialIbGibType,\n /** indexes all tjp addresses that automatically sync. */\n autosyncs: \"autosyncs\" as SpecialIbGibType,\n robbots: \"robbots\" as SpecialIbGibType,\n apps: \"apps\" as SpecialIbGibType,\n /** timelines history */\n history: \"history\" as SpecialIbGibType,\n}\n\n/**\n * There has been a new ibGib that is the latest for a given tjp timeline.\n */\nexport interface IbGibTimelineUpdateInfo extends IbGib_V1 {\n ib: 'IbGibTimelineUpdateInfo',\n tjpAddr?: IbGibAddr;\n latestAddr: IbGibAddr;\n latestIbGib?: IbGib_V1<any>;\n}\n\n/**\n * Serializing helper type for compressing dependency graphs.\n */\nexport type SerializedUint8Array = {\n _dataType: 'Uint8Array_Base64';\n value: string;\n};\n", "/**\n * In a Robbot's rel8ns, this is the rel8n name that links to tags that the\n * Robbot uses for tagging its output.\n */\nexport const ROBBOT_TAG_TJP_ADDRS_REL8N_NAME = 'tagTjpAddrs';\n/**\n * A spaces ibGib uses this rel8n name for related sync spaces, used\n * in replicating ibgib spaces.\n */\nexport const ROBBOT_REL8N_NAME = 'robbot';\n/**\n * When a robbot witnesses an ibgib, it will \"remember\" the ibgib\n * by relating the target ibgib to itself via this rel8nName.\n */\nexport const DEFAULT_ROBBOT_TARGET_REL8N_NAME = 'x';\n\n/**\n * wah wah wah...\n */\nexport const IBGIB_ROBBOT_NAME_DEFAULT = 'i';\n\n/**\n * Icon for a single robbot\n */\nexport const DEFAULT_ROBBOT_ICON = 'body-outline';\n", "import { GIB } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\n/**\n * Zero space is a default space that uses default values that should be\n * reproducible and not break or something...it's all in flux really.\n */\nexport const ZERO_SPACE_ID = 'zero';\n\n/**\n * was 000_default_space in MVP. need to add a conversion\n */\nexport const IBGIB_SPACE_NAME_DEFAULT = 'zerospace';\n// export const IBGIB_SPACE_NAME_DEFAULT = 'default_space';\n\n\n/**\n * For use with documentation and UX help.\n *\n * This is probably scoped to a particular schema...(e.g. v1)\n */\nexport const VALID_SPACE_NAME_EXAMPLES = [\n 'justLetters', 'valid_here', 'hyphens-allowed', '0CanStartOrEndWithNumbers9'\n];\n/**\n * For use with documentation and UX help.\n *\n * This is probably scoped to a particular schema...(e.g. v1)\n */\nexport const INVALID_SPACE_NAME_EXAMPLES = [\n 'IHaveASymbol!', 'invalid hereWithSpace', '-cantStartWithHyphen', '_OrUnderscore'\n];\n\n/**\n *\n */\nexport const PERSIST_OPTS_AND_RESULTS_IBGIBS_DEFAULT = false;\n\n/**\n * Yep, this one starts with default instead of ending with it.\n */\nexport const DEFAULT_LOCAL_SPACE_DESCRIPTION = `This is a local space. There are many like it, but this one is mine.`;\n\n/**\n * The main roots^gib ibgib uses this rel8n name to keep track of roots.\n */\nexport const SPACE_REL8N_NAME = 'space';\n\n/**\n * rel8n name in a space ibgib to the config ibgib(s?)\n */\nexport const SPACE_REL8N_NAME_CONFIG = `config`;\n/**\n * note that atow this is implied in the regexp not derivative\n * @see {@link SPACE_NAME_REGEXP}\n */\nexport const SPACE_NAME_MAX_LENGTH = 64;\n/**\n * alphanumerics start + end, middle can also contain hyphens atow.\n *\n * NOTE: this implies the value of {@link SPACE_NAME_MAX_LENGTH} but this is not\n * derived from the value. so if you change this, be sure to change/check that\n *\n * @see {@link SPACE_NAME_MAX_LENGTH}\n */\nexport const SPACE_NAME_REGEXP = /^[a-zA-Z][\\w\\-]{0,62}[a-zA-Z]$/;\n\n/**\n * A spaces ibGib uses this rel8n name for related sync spaces, used\n * in replicating ibgib spaces.\n */\nexport const SYNC_SPACE_REL8N_NAME = 'syncSpace';\n\n/**\n * ...?\n */\nexport const DEFAULT_SPACE_TEXT = 'space';\n/**\n * Default icon specifically for spaces.\n */\nexport const DEFAULT_SPACE_ICON = 'sparkles-outline';\n/**\n * Default description specifically for spaces.\n */\nexport const DEFAULT_SPACE_DESCRIPTION =\n `This is a space ibgib, which is basically a special ibgib who has behavior\nto interface with data stores and/or other space(s) to provide concrete location\nfor ibgibs. All ibgibs can have relationships with other ibgibs, but this one\nspecifically either implies a physical interface to things like databases,\nfile systems, and similar; OR, when this space interfaces with other spaces, this\nis a logical organization of ibgib locations, like when configuring clusters or\nconsensus algorithms.`;\n/**\n * rel8n name used inside the root to those ibgib it contains.\n *\n * @example\n * ```json\n * {\n * ib: root,\n * gib: ABC123,\n * data: {...},\n * rel8ns: {\n * [rel8nName]: [\"a^1\", \"b^2\"]\n * }\n * }\n * ```\n */\nexport const DEFAULT_SPACE_REL8N_NAME = 'x';\n\n/**\n * Interval in ms between polling for updates (\"notifications\") between local\n * space (ibgibs service) and dynamo sync space(s), or for use within a single\n * space for checking its internal state.\n *\n * Of course, long polling is very hacky, but so is using DynamoDB in the cloud\n * for a sync space. Obviously need to progress to a more mature and robust sync\n * space/outer space architecture.\n */\nexport const DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS = 30_000;\nexport const DEFAULT_LOCAL_SPACE_POLLING_DELAY_FIRST_RUN_MS = 10_000;\n\n/**\n * it's a space\n */\nexport const SPACE_ATOM = 'space';\n\n/**\n * {@link DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS} but for outer spaces, so\n * longer interval atow.\n */\nexport const DEFAULT_OUTER_SPACE_POLLING_INTERVAL_MS = 20_000;\n/**\n * Amount of time to delay for FIRST poll execution.\n */\nexport const DEFAULT_OUTER_SPACE_POLLING_DELAY_FIRST_RUN_MS = 10_000;\n\n/**\n * When a status is first created, this is used to indicate that\n * the tjp has not been set.\n */\nexport const STATUS_UNDEFINED_TJP_GIB = GIB;\n/**\n * When a status is first created, this is used to indicate that\n * the txId has not been set.\n */\nexport const STATUS_UNDEFINED_TX_ID = '0';\n\nexport const SPACE_LOCK_IB_TERM = 'space_lock';\n/**\n * When attempting to acquire a lock ona space, and it is already lock, it will\n * wait a random amount of ms before trying to lock again. This is the default\n * max amount of ms before reattempting.\n */\nexport const DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE = 100;\n/**\n * Will retry this many times before giving up...\n */\nexport const DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS = 100;\n/**\n * We don't want someone locking a space forever by accident.\n */\nexport const MAX_LOCK_SECONDS_VALID = 60 * 2; // two minutes\n/**\n * Default value for secondsValid when acquiring/releasing lock in/on LOCAL\n * space.\n */\nexport const DEFAULT_SECONDS_VALID_LOCAL = 30;\n/**\n * Default value for secondsValid when acquiring/releasing lock in/on\n * OUTER space, e.g. sync spaces like aws dynamo sync space.\n */\nexport const DEFAULT_SECONDS_VALID_OUTER = 30;\n\n/**\n * retry count when calling getDependencyGraph.\n *\n * ## driving use case\n *\n * dependency graph fails when concurrent merges made in sync space.\n * need to wait until previous graph merger happens then retry.\n */\nexport const DEFAULT_MAX_RETRIES_GET_DEPENDENCY_GRAPH_OUTERSPACE = 5;\n/**\n * when getting dependency graph, sometimes we have to wait to retry\n */\nexport const DEFAULT_MS_BETWEEN_RETRIES_GET_DEPENDENCY_GRAPH_OUTERSPACE = 5000;\n/**\n * retry count when calling getDependencyGraph.\n *\n * ## driving use case\n *\n * dependency graph fails when concurrent merges made in sync space.\n * need to wait until previous graph merger happens then retry.\n */\nexport const DEFAULT_MAX_RETRIES_GET_DEPENDENCY_GRAPH_LOCAL = 3;\n/**\n * when getting dependency graph, sometimes we have to wait to retry\n */\nexport const DEFAULT_MS_BETWEEN_RETRIES_GET_DEPENDENCY_GRAPH_LOCAL = 1000;\n\n/**\n * currently not used in ionic-gib.\n */\nexport const DEFAULT_TX_ID_LENGTH = 5;\n", "/**\n * The main roots^gib ibgib uses this rel8n name to keep track of roots.\n *\n * NOTE: This is different than the rel8nName that a root ibgib uses to link to its ibgibs!\n * {@link DEFAULT_ROOT_REL8N_NAME}\n */\nexport const ROOT_REL8N_NAME = 'root';\n\n/**\n * rel8n name used inside the root to those ibgib it contains. (root.rel8ns.x = [pic1^gib, comment2^gib, ...])\n *\n *\n * NOTE: This is different than the rel8nName 'root' that the roots^gib uses. (roots.rel8ns.root = [root1^gib, root2^gib, ...])\n * {@link ROOT_REL8N_NAME}\n *\n * @example\n * ```json\n * {\n * ib: root,\n * gib: ABC123,\n * data: {...},\n * rel8ns: {\n * [rel8nName]: [\"a^1\", \"b^2\"]\n * }\n * }\n * ```\n */\nexport const DEFAULT_ROOT_REL8N_NAME = 'x';\n\n/**\n *\n */\nexport const DEFAULT_ROOT_TEXT = 'root';\n/**\n * Default icon specifically for roots.\n */\nexport const DEFAULT_ROOT_ICON = 'analytics-outline';\n/**\n * Default description specifically for roots.\n */\nexport const DEFAULT_ROOT_DESCRIPTION = 'This is a root ibgib, which is basically like a root folder that is primarily responsible for \"containing\" other ibgibs.';\n", "// export const TAGS_IB = 'tags';\n// export const TAGS_IBGIB_ADDR = `${TAGS_IB}^${GIB}`;\n// export const TAGS_IBGIB_ADDR_KEY = `key ${TAGS_IBGIB_ADDR}`;\n\n/**\n * The main tags^gib ibgib uses this rel8n name to keep track of tags.\n */\nexport const TAG_REL8N_NAME = 'tag';\n\n/**\n * A tag ibGib uses this rel8n name for the ibgibs that it targets.\n */\nexport const TAG_TARGET_REL8N_NAME = 'target';\n\n\nexport const ILLEGAL_TAG_TEXT_CHARS = [\n '^', '?', '/', '\\\\', `|`,\n];\n\nexport const ILLEGAL_TAG_DESC_CHARS = [\n '^',\n];\n\n/**\n * Default icon when creating a tag.\n */\nexport const DEFAULT_TAG_ICON = 'pricetag-outline';\n/**\n * Default description when creating a tag.\n */\nexport const DEFAULT_TAG_DESCRIPTION = 'This is a tag used for organizing data.';\n\n// export const TAG_TEXT_REGEXP = /^\\w[\\w .\\-?!]{1,30}[\\w.?!]$/;\n// export const TAG_TEXT_REGEXP_DESCRIPTION = `tag text must start and end with an alphanumeric, and can contain a hyphen, question mark, dot or space.`;\n", "/**\n * @module\n *\n * not quite sure where these go.\n *\n * todo: check after the project is building where these other-constants fit.\n */\n\n/**\n * default id settings where...?\n */\nexport const DEFAULT_UUID = undefined;\n\nimport { ROBBOT_REL8N_NAME } from '../../witness/robbot/robbot-constants.mjs';\nimport { SYNC_SPACE_REL8N_NAME } from '../../witness/space/space-constants.mjs';\nimport { DEFAULT_ROOT_REL8N_NAME, ROOT_REL8N_NAME } from '../root/root-constants.mjs';\nimport { TAG_TARGET_REL8N_NAME, TAG_REL8N_NAME } from '../tag/tag-constants.mjs';\n\nexport const AUTOSYNC_ALWAYS_REL8N_NAME = 'always';\nexport const ARCHIVE_REL8N_NAME = 'archive';\nexport const TRASH_REL8N_NAME = 'trash';\n\n/**\n * These rel8n names are shown in a list view by default.\n *\n * This should perhaps go into a chat or common ux constants?\n */\nexport const DEFAULT_LIST_REL8N_NAMES: string[] = [\n 'pic', 'comment', 'link',\n 'result', 'import',\n 'tagged',\n TAG_TARGET_REL8N_NAME,\n TAG_REL8N_NAME,\n ROOT_REL8N_NAME, // hack for now to get all to show\n DEFAULT_ROOT_REL8N_NAME,\n ROBBOT_REL8N_NAME,\n SYNC_SPACE_REL8N_NAME,\n];\n\n/**\n *\n */\nexport const CURRENT_VERSION = '1';\n\n/**\n * List of common special chars for english.\n *\n * ## intent\n *\n * When sanitizing input.\n */\nexport const ALLISH_SPECIAL_CHARS = `\\`~!@#$%^&*()_\\\\-+=|\\\\\\\\\\\\]}[{\"':;?/>.<,`;\nexport const FILENAME_SPECIAL_CHARS = ` \\`~!@#$%&*()_\\\\-+=|\\\\]}[{\"';?>.<,`;\n\n/**\n * If this matches, then we will encode the data field in our storage (aws\n * anyway atow)\n */\nexport const IBGIB_DATA_REGEX_INDICATES_NEED_TO_ENCODE = /[^\\w\\s\\d`~!@#$%\\^&*()_\\\\\\-+=|\\]\\}\\[\\{\"':;?/>.<,]/;\n\n/**\n * hacky scroll to bottom after items load per platform\n */\nexport const DEFAULT_SCROLL_DELAY_MS_WEB_HACK = 5_000;\n/**\n * hacky scroll to bottom after items load per platform\n */\nexport const DEFAULT_SCROLL_DELAY_MS_ANDROID_HACK = 3_000;\n/**\n * hacky scroll to bottom after items load per platform\n */\nexport const DEFAULT_SCROLL_DELAY_MS_IOS_HACK = 2_000;\n\n/**\n * when you create a meta special ibgib, it must just be some alphanumerics.\n */\nexport const SPECIAL_IBGIB_TYPE_REGEXP = /^\\w{1,32}$/;\n\n/**\n * big weird decision in JS this one...\n */\nexport const INVALID_DATE_STRING = \"Invalid Date\";\n", "import { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\"\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\"\n\n/**\n * primitive ibgib for indicating a true value\n */\nexport const TRUE_GIB: IbGib_V1 = { ib: 'true', gib: GIB }\n/**\n * primitive ibgib for indicating a truthy value\n */\nexport const TRUTHY_GIB: IbGib_V1 = { ib: 'truthy', gib: GIB };\n/**\n * primitive ibgib for indicating a false value\n */\nexport const FALSE_GIB: IbGib_V1 = { ib: 'false', gib: GIB }\n/**\n * primitive ibgib for indicating a falsy value\n */\nexport const FALSY_GIB: IbGib_V1 = { ib: 'falsy', gib: GIB }\n\n/**\n * config entries in space rel8ns/data will start with this\n */\nexport const CONFIG_KEY_ATOM = 'config_key';\n", "import { Ib } from '@ibgib/ts-gib/dist/types.mjs';\n\nexport const DEFAULT_META_IB_STARTS: Ib[] = [\n 'tags', 'tag ', 'settings', 'setting ', 'witness space ',\n]\nexport const SPECIAL_URLS = [\n 'tags', 'home'\n];\n\n/**\n * When showing a menu item, this is the max length\n */\nexport const MENU_ITEM_IB_SUBSTRING_LENGTH = 20;\n\nexport const QUERY_PARAM_PAUSED = 'paused';\nexport const QUERY_PARAM_ROBBOT = 'robbot';\n\nexport const APP_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,32}$/;\nexport const APP_REL8N_NAME = 'app';\n", "import { GIB } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\n/**\n * See {@link BootstrapIbGib}\n */\nexport const BOOTSTRAP_IBGIB_ADDR = `bootstrap^${GIB}`;\n/**\n * {@see BootstrapData}\n */\nexport const BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY = `defaultSpaceId`;\n/**\n * Key for index tracking known spaceIds in a bootstrap ibgib.\n * {@see BootstrapData}\n */\nexport const BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY = `spaceIds`;\n", "/**\n * There are multiple ways to incorporate the salt into the overall algorithm.\n * See the individual constant properties for details.\n *\n * {@link SaltStrategy} constant\n */\nexport type SaltStrategy =\n 'prependPerHash' | 'appendPerHash' |\n 'initialPrepend' | 'initialAppend';\n/**\n * enum-like constant for use in tandem with `SaltStrategy` type.\n *\n * See the individual constant properties for details.\n */\nexport const SaltStrategy = {\n /**\n * EACH time we hash anything in a round function or initial key-stretching,\n * we will prepend the salt via string concatenation with the secret, if\n * initial (salt + secret), else with the previous hash (salt + prev).\n */\n prependPerHash: 'prependPerHash' as SaltStrategy,\n /**\n * EACH time we hash anything in a round function or initial key-stretching,\n * we will append the salt via string concatenation with the secret, if\n * initial (secret + salt), else with the previous hash (prev + salt).\n */\n appendPerHash: 'appendPerHash' as SaltStrategy,\n /**\n * We will only prepend the salt to the secret (salt + secret) via string\n * concatenation ONLY in the initial key-stretching recurions phase.\n */\n initialPrepend: 'initialPrepend' as SaltStrategy,\n /**\n * We will only append the salt to the secret (secret + salt) via string\n * concatenation ONLY in the initial key-stretching recurions phase.\n */\n initialAppend: 'initialAppend' as SaltStrategy,\n} as const satisfies { [key: string]: SaltStrategy };\n/**\n * convenience constant array containing all of `Object.values(SaltStrategy)`\n */\nexport const SALT_STRATEGIES: SaltStrategy[] = Object.values(SaltStrategy);\n\n/**\n * Hash algorithm type.\n *\n * atow this is only SHA-256 and SHA-512 because both of these are relatively\n * strong and are supported in both node and browser environments. I have found\n * conflicting information on whether or not these are post-quantum secure.\n */\nexport type HashAlgorithm = 'SHA-256' | 'SHA-512';\n/**\n * enum-like constant for use in tandem with `HashAlgorithm` type.\n */\nexport const HashAlgorithm = {\n 'sha_256': 'SHA-256' as HashAlgorithm,\n 'sha_512': 'SHA-512' as HashAlgorithm,\n} satisfies { [key: string]: HashAlgorithm };\nexport const HASH_ALGORITHMS: HashAlgorithm[] = Object.values(HashAlgorithm);\n\nexport type AlphabetIndexingMode = 'indexOf' | 'lastIndexOf';\n/**\n * when iterating characters, this determines whether we are using `'indexOf'` or\n * `'lastIndexOf'` on the alphabet string.\n *\n * So if the JIT hex alphabet is abc123abc456 and our character is b:\n *\n * abc123abc456\n * ^ ^\n * 1\n * * `'indexOf'` -> 1\n * * `'lastIndexOf'` -> 7\n *\n * with immediately expanding JIT alphabets, this shouldn't make much of a\n * difference. But when mitigating brute force short-circuit attacks, where\n * the brute forcer only decrypts the first couple of characters of data, we\n * may combine `'lastIndexOf'` with a \"multipass\" expanding alphabet to\n * ensure that a larger portion of the plaintext (up to 100% of the\n * plaintext), is required to be processed before any short-circuiting\n * decryption can occur. @see {@link BlockModeOptions}\n *\n * To help understand this, here is an example. Say we use a multi-pass\n * alphabet that requires a minimum of 3 expansions. We encipher the first\n * character of plaintext we first convert that character to hex. Say this\n * hex is 'a'. Now we create our corresponding alphabet by recursively\n * rounding on the initial `prevHash` (after key stretching with\n * `initialRecursions` has occurred). Say one round produces a hash\n * '123a56ba90' for our one-time JIT alphabet. If this were an immediately\n * expanding JIT alphabet with no minimum expansions and the ciphertext is\n * already present, then additional rounds won't be needed for the attacker\n * - they already have the index and the alphabet that has the plaintext.\n *\n * With `lastIndexOf` + multipass blocks, then the attacker is forced to\n * calculate at least the entire section's hashing because the encrypted\n * index will most likely be at the end of the alphabet.\n *\n * abc123...[200ish hex character]...bac231\n * ^\n * The first `indexOf('2')` would just be 4, and no other alphabet\n * extensions would be required (not a single one in the section). Whereas\n * the `lastIndexOf('2')` would be a 200+ index. This would require multiple\n * hashes for every previous character in the section, and would thus harder\n * to short-circuit.\n *\n * @default `'indexOf'`\n */\nexport const AlphabetIndexingMode = {\n indexOf: 'indexOf',\n lastIndexOf: 'lastIndexOf',\n} satisfies { [key: string]: AlphabetIndexingMode };\nexport const ALPHABET_INDEXING_MODES: AlphabetIndexingMode[] = Object.values(AlphabetIndexingMode);\n\n/**\n * # tl;dr\n *\n * Block mode is stronger but slower relative to the stream mode.\n *\n * When block mode is enabled, we do multiple passes on sections of plaintext\n * when encrypting/decrypting.\n *\n * This is one way to help mitigate against short-circuit brute force\n * attacks.\n *\n * # how it works\n *\n * The block-mode algorithm works as follows:\n *\n * ## encrypting\n *\n * * plaintext characters - p0, p1, .., pi\n * * JIT alphabet hashes - [a0.0, a0.1, a0.2, .., a0.j], [a1.0, a1.1, a1.2, .., a1.j], .., [ai.0, ai.1, ai.2, .., ai.j]\n * * i = plaintext index\n * * j = alphabet expansion index\n * * passes - PASS1, PASS2, .., PASSn\n *\n * 1. First we iterate through the plaintext data in multipass blocks, the\n * size of which is parameterized by `maxBlockSize`. If this is larger\n * than data, then the entire plaintext will be used.\n *\n * 2. Then we create the initial alphabets for the entire section, determined by\n * our pass section size and the number of passes.\n *\n * 3. We then extend any individual alphabets that do not contain an instance of\n * the plaintext character yet. We are extending only those alphabets in need of\n * extending, as opposed to the previous step where we extended all alphabets in\n * the pass section.\n *\n * 4. We get the index of each plaintext character into its corresponding\n * alphabet and store each index in an array for the entire multipass block.\n * We then concat this new section with any previous sections encrypted,\n * building out our entire result `encryptedData` array section by section.\n *\n * 5. Lastly, we return the array as a string, joining each index with the\n * parameterized delimiter (comma by default).\n *\n * ## decrypting\n *\n * The decryption process is very similar.\n *\n * 1. First we iterate through the ciphertext data in multipass blocks, the\n * size of which must be the same as the encryption process (all parameters\n * should be the same encrypting and decrypting. these are automatically stored\n * in encryption output file).\n *\n * 2. Next we create our alphabets for the entire section. The first phase of\n * this is to build out the minimum sized alphabets per parameters\n * (`numOfPasses`).\n *\n * 3. Next we iterate through the encryped indexes for the section. While the\n * index is larger than the existing alphabet, the alphabet is JIT extended by\n * the hash round function. Once the alphabet is large enough (i.e. the\n * encrypted index can index into it), the the encrypted index is used in the\n * alphabet and the plaintext hex character is stored in a result array for the\n * section.\n *\n * 4. Once the entire section is decrypted to hex, the section's plaintext array\n * is added to the previously decrypted sections' plaintext results.\n *\n * 5. Once all sections are decrypted to hex, the plaintext array is converted to a\n * hex string and then decoded to the original plaintext.\n */\nexport interface BlockModeOptions {\n /**\n * Maximum number of **hex-encoded** plaintext characters per section when\n * making multiple passes. Each pass extends the JIT alphabet for each\n * character in that pass by the length of the hash digest being used (since\n * the hashes are what the alphabets are made of).\n *\n * * If this is greater than the hex-encoded `dataToEncrypt` length, then\n * each pass section will be the length of data (it's goin to do the whole\n * plaintext in one section).\n * * Barring internal JS voodoo, each pass should require additional memory\n * roughly linearly proportional to\n * * `dataToEncrypt`/`maxBlockSize` length (whichever is smaller)\n * * `numOfPasses` to make\n * * length of the hash used in creating the JIT alphabets (`hashAlgorithm`)\n * * The larger `maxBlockSize` & `numOfPasses` is, the more a brute\n * force attack has to calculate - and the more memory it is going to take\n * - before determining if a secret guess is correct.\n */\n maxBlockSize: number;\n /**\n * @deprecated\n *\n * use {@link maxBlockSize}\n */\n maxPassSectionLength?: number;\n /**\n * Number of \"passes\" to make over the pass section. Each pass will extend\n * the JIT alphabet for each character in the pass section by the length of\n * the hash digest string used in `hashAlgorithm`.\n *\n * This should be especially effective in mitigating against brute force\n * cracking when used in tandem with an `indexingMode` of `lastIndexOf`.\n * This is because at least `(numOfPasses - 1) * maxBlockSize`\n * number of hash rounds must be calculated before the very first plaintext\n * character can be deciphered. This is even more expensive if\n * `recursionsPerHash` is larger.\n */\n numOfPasses: number;\n}\n\n/**\n * Shared interface among both args and results.\n *\n * ## notes\n *\n * Silly name... naming things hrmm.\n */\ninterface BaseBase {\n /**\n * how to index into the jit alphabet\n *\n * @see {@link AlphabetIndexingMode}\n */\n indexingMode?: AlphabetIndexingMode;\n /**\n * Settings to use if we want to use multiple passes when\n * encrypting/decrypting.\n *\n * This is one way to help mitigate against short-circuit brute force\n * attacks.\n *\n * @see {@link BlockModeOptions}\n */\n blockMode?: BlockModeOptions;\n /**\n * @deprecated\n *\n * Use `blockMode` instead.\n */\n multipass?: BlockModeOptions;\n /**\n * The hash algorithm to use.\n *\n * ATOW, this is either 'SHA-256' or 'SHA-512'.\n *\n * @see {@link HashAlgorithm} for current values.\n */\n hashAlgorithm?: HashAlgorithm;\n /**\n * The amount of recursions from the secret + salt to start actual\n * encryption mapping.\n *\n * The bigger this is, the more time it takes to try guesses for an\n * attacker, depending on how expensive the hash function is. But also the\n * more time it would take on the legitimate user's password attempt.\n */\n initialRecursions: number;\n /**\n * The number of recursive hashes we perform for each round function of\n * hashing (except the initial recursions, see `initialRecursions` param).\n *\n * This includes both when we hash each hex character of our hex-encoded\n * data, as well as each time we JIT extend the alphabet when the plaintext\n * hex character isn't found in the current JIT hash alphabet.\n *\n * So, if the initial hash alphabet is all a's (e.g. \"aaa...a\", a very\n * contrived hash!), but our hex data is a b, then we will hash the all-a\n * hash {recursionsPerHash} times to expand the alphabet.\n *\n * @example\n * So if we have a data character of 'b', and its immediate hash alphabet is\n * all a's, and we recurse 3 times per hash (ignoring salts for this\n * example), here is some simplified pseudo code to give the gist:\n *\n * ```javascript\n * dataCharToMap = 'b';\n * alphabet = hash(prevHash) // say it gives us 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';\n * needExpandAlphabet = alphabet.includes(dataCharToMap) // false in this case\n * if (needExpandAlphabet) {\n * hashToAdd = alphabet;\n * for (i = 0; i < recursionsPerHash; i++) { hashToAdd = hash(hashToAdd); }\n * alphabet = alphabet + hashToAdd; // say it's now 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab';\n * }\n * index = alphabet.indexOf(dataCharToMap); // 63\n * ```\n *\n * In actuality, the code will include salt and saltStrategy, and track how\n * many times the alphabet expands to get the correct index.\n *\n * Note that this does not add on each and every recursive hash produced. It\n * only adds on the last hash after recursionsPerHash number of hashes (i.e.\n * the alphabet is JIT extended the length of a single hash digest - the\n * last one).\n */\n recursionsPerHash?: number;\n /**\n * text to prepend/append to hashes for increased security.\n *\n * {@link SaltStrategy}\n */\n salt: string;\n\n /**\n * {@link SaltStrategy}\n */\n saltStrategy?: SaltStrategy;\n /**\n * Encrypted data is just an array of numbers (positive integers).\n * This array is converted to a string by joining with a delimiter.\n * This is that delimiter.\n *\n * @default DEFAULT_ENCRYPTED_DATA_DELIMITER in constants.ts\n */\n encryptedDataDelimiter?: string;\n}\n\n/**\n * Args-specific info, in contrast to result-specific info\n *\n * @see {@link BaseResult}\n */\nexport interface BaseArgs extends BaseBase {\n secret: string;\n}\n\n/**\n * Info passed to the `encrypt` function.\n */\nexport interface EncryptArgs extends BaseArgs {\n /**\n * Plaintext data string\n */\n dataToEncrypt: string;\n /**\n * If true, will decrypt back and confirm that the decryption was\n * successfully performed and the original plaintext is recoverable via the\n * decryption process.\n *\n * Takes more time & resources.\n */\n confirm?: boolean;\n}\n\n/**\n * Info passed to the `decrypt` function.\n */\nexport interface DecryptArgs extends BaseArgs {\n /**\n * String of delimited encrypted indexes.\n */\n encryptedData: string;\n}\n\n/**\n * Result-specific info, in contrast to args-specific info\n *\n * @see {@link BaseArgs}\n */\ninterface BaseResult extends BaseBase {\n /**\n * If truthy, there were big problems...\n */\n errors?: string[];\n /**\n * If truthy, there were issues...\n */\n warnings?: string[];\n}\n\n/**\n * Result info from `encrypt` function.\n */\nexport interface EncryptResult extends BaseResult {\n /**\n String of delimited encrypted indexes.\n */\n encryptedData?: string;\n}\n\n/**\n * Result info from `decrypt` function.\n */\nexport interface DecryptResult extends BaseResult {\n decryptedData?: string;\n}\n", "/**\n * @module helper utility functions specific to encrypt-gib\n *\n * THANK YOU Stack Overflow, Simon Buchan, and others at https://stackoverflow.com/questions/21647928/javascript-unicode-string-to-hex\n */\n\nimport { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\n\n\n/**\n * Convert some string to a string with only hex characters.\n *\n * Should (hopefully!) be reversible.\n *\n * @param s string to convert to hex string\n * @returns string that only contains hexidecimal characters (0-9, a-f)\n */\nexport function encodeStringToHexString(s: string): Promise<string> {\n const lc = `[${encodeStringToHexString.name}]`;\n return new Promise((resolve, reject) => {\n try {\n let bytes = stringToUTF8Bytes(s);\n let hexString = bytesToHexString(bytes);\n resolve(hexString);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n }\n });\n}\n\nfunction stringToUTF8Bytes(s: string): Uint8Array {\n const lc = `[${stringToUTF8Bytes.name}]`;\n try {\n return new TextEncoder().encode(s);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nfunction bytesToHexString(bytes: Uint8Array): string {\n const lc = `[${bytesToHexString.name}]`;\n try {\n return Array.from(\n bytes,\n byte => byte.toString(16).padStart(2, '0')\n ).join(\"\");\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Decodes the hex-encoded string back to the original text.\n *\n * @param hexString Encoded x of some some data string\n * @returns Decoded (original hopefully!) text\n */\nexport function decodeHexStringToString(hexString: string): Promise<string> {\n const lc = `[${decodeHexStringToString.name}]`;\n return new Promise((resolve, reject) => {\n try {\n // console.log(`${lc} hexString (len: ${hexString.length}): ${hexString}`);\n const bytes = hexStringToBytes(hexString);\n const s = utf8BytesToString(bytes);\n resolve(s);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n reject(error);\n }\n });\n}\n\n/**\n * Converts hex to bytes.\n *\n * Ty also https://stackoverflow.com/questions/14603205/how-to-convert-hex-string-into-a-bytes-array-and-a-bytes-array-in-the-hex-strin\n *\n * @param hexString string that (obviously) should be hex to convert to bytes\n */\nfunction hexStringToBytes(hexString: string): Uint8Array {\n const lc = `[${hexStringToBytes.name}]`;\n try {\n // console.log(`${lc} hexString (len: ${hexString.length}): ${hexString}`);\n if (hexString.length % 2 !== 0) { throw new Error(`invalid hex string. length %2 !== 0`); }\n const numBytes = hexString.length / 2;\n const bytes = new Uint8Array(numBytes);\n for (let i = 0; i < numBytes; i++) {\n bytes[i] = parseInt(hexString.substr(i * 2, 2), 16);\n }\n return bytes;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\nfunction utf8BytesToString(bytes: Uint8Array): string {\n const lc = `[${utf8BytesToString.name}]`;\n try {\n return new TextDecoder().decode(bytes);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"./index.mjs\";\n\nexport const ENCRYPT_LOG_A_LOT = false;\n\nexport var DEFAULT_SALT_STRATEGY: SaltStrategy = SaltStrategy.appendPerHash;\n// export var DEFAULT_HASH_ALGORITHM: HashAlgorithm = 'SHA-256';\nexport var DEFAULT_HASH_ALGORITHM: HashAlgorithm = 'SHA-512';\nexport var DEFAULT_GETUUID_SEEDSIZE: number = 1024;\nexport var DEFAULT_INITIAL_RECURSIONS: number = 20000;\nexport var DEFAULT_RECURSIONS_PER_HASH: number = 1;\n/**\n * This must be indexOf for backwards compatibility.\n */\nexport var DEFAULT_ALPHABET_INDEXING_MODE_LEGACY: AlphabetIndexingMode = 'indexOf';\n/**\n * In multipass, which is being developed to help mitigate against short-circuit\n * brute force attacks, I believe it's safer to use `lastIndexOf` in order to\n * leverage the alphabet extensions in other options. This may turn out to be\n * unnecessary.\n */\nexport var DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE: AlphabetIndexingMode = 'lastIndexOf';\n/**\n * Default value for the maximum size of a block, when using block mode (if the\n * total plaintext data is smaller than this, then the effective block size is\n * that data's length).\n *\n * This is essentially how many groups of hex-encoded plaintext characters are\n * we going to iterate on at one time with multiple passes. So if you have a\n * block size of 1000, then the block mode encryption will have to keep in\n * memory (or store/retrieve dynamically if an attacker rewrites this library's\n * internals) at least 1000 hashes for the entire block before being able to\n * compute the second pass's hash of the first character. So for 2 passes and a\n * hashLength (digestLength) of 64 bytes, this would be roughly 1000 *\n * hashLength bytes * (numOfPasses - 1)~~> 64 kB of memory. (though really I\n * think this is 128 kB because current implementation just treats the digest as\n * a string)\n *\n * Used in block mode.\n */\nexport var DEFAULT_MAX_BLOCK_SIZE: number = 5_000_000;\n/**\n * Default value for the number of passes when using block mode.\n *\n * Used in block mode\n */\nexport var DEFAULT_NUM_OF_PASSES: number = 4;\n\nexport var DEFAULT_ENCRYPTED_DATA_DELIMITER: string = ',';\n", "import { extractErrorMsg, hash as hashFn } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Builds the string that we will hash to get the next hash alphabet.\n *\n * @example\n * if we're prepending every hash, and this is the initial hash,\n * then we'll return `salt + secret`.\n *\n * @returns the string we're going to hash to get the next alphabet\n */\nexport function getPreHash({\n secret,\n prevHash,\n salt,\n saltStrategy,\n}: {\n secret?: string,\n prevHash?: string,\n salt: string,\n saltStrategy: SaltStrategy,\n}): string {\n if (!(prevHash || secret)) { throw new Error(`Either secret or prevHash is required, but both are falsy (E: bee2849729ff410081d963777dcedb49))`); }\n // either prevHash or secret is guaranteed for all the following cases\n switch (saltStrategy) {\n case SaltStrategy.prependPerHash:\n return salt + (prevHash || secret)\n case SaltStrategy.appendPerHash:\n return (prevHash || secret) + salt;\n case SaltStrategy.initialPrepend:\n return prevHash ? prevHash : salt + secret;\n case SaltStrategy.initialAppend:\n return prevHash ? prevHash : secret + salt;\n default:\n throw new Error(`Unknown saltStrategy: ${saltStrategy} (E: 235136af1a6c40eb9c17b2ca41c08a01)`);\n }\n}\n\nexport async function execRound_getNextHash({\n secret,\n prevHash,\n count,\n salt,\n saltStrategy,\n hashAlgorithm,\n}: {\n secret?: string,\n prevHash?: string,\n count: number,\n salt: string,\n saltStrategy: SaltStrategy,\n hashAlgorithm: HashAlgorithm,\n}): Promise<string> {\n const lc = `[${execRound_getNextHash.name}]`;\n try {\n let hash = prevHash || undefined;\n for (let i = 0; i < count; i++) {\n const preHash = getPreHash({ secret, prevHash: hash, salt, saltStrategy });\n hash = await hashFn({ s: preHash, algorithm: hashAlgorithm });\n }\n if (!hash) { throw new Error(`hash was not created (E: 09dfdfd644734727a34a1bc0bd8e93b9)`); }\n return hash;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Creates the first \"alphabet\" that we will index into.\n *\n * We have this separate, because the initialRecursions help us\n * chug on the secret.\n *\n * If the data's hex character is not in this alphabet, it will\n * be expanded just as any\n */\nexport async function doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy,\n hashAlgorithm,\n}: {\n secret: string,\n initialRecursions: number,\n salt: string,\n saltStrategy: SaltStrategy,\n hashAlgorithm: HashAlgorithm,\n}): Promise<string> {\n const lc = `[${doInitialRecursions_keystretch.name}]`;\n try {\n const hash = await execRound_getNextHash({\n secret,\n count: initialRecursions,\n salt, saltStrategy, hashAlgorithm,\n })\n return hash;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, } from \"../common/encrypt-decrypt-common.mjs\";\nimport { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Does the actual encryption from hexEncodedData with the given params.\n *\n * @returns encryptedData\n */\nexport async function encryptFromHex_stream({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n}: {\n hexEncodedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n indexingMode: AlphabetIndexingMode,\n}): Promise<string> {\n const lc = `[${encryptFromHex_stream.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n // console.log(`${lc} first prevHash: ${prevHash}`);\n\n const getIndex: (alphabet: string, hexChar: string) => number =\n indexingMode === 'indexOf' ?\n (alphabet: string, hexChar: string) => { return alphabet.indexOf(hexChar) } :\n (alphabet: string, hexChar: string) => { return alphabet.lastIndexOf(hexChar) };\n // console.log(`${lc} using getIndex (indexingMode: ${indexingMode})`);\n\n // we have our prevHash starting point, so now we can iterate through the data\n let encryptedDataIndexes: number[] = [];\n for (let i = 0; i < hexEncodedData.length; i++) {\n // this is the character of data that we want to map to an index into the generated alphabet\n const hexCharFromData: string = hexEncodedData[i];\n let alphabet: string = \"\";\n let hash: string;\n while (!alphabet.includes(hexCharFromData)) {\n // if (alphabet.length > 64) {\n // console.log(`alphabet is extending past 64... alphabet.length: ${alphabet.length}`);\n // }\n // console.log(`${lc} doing iteration...`);\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash!;\n prevHash = hash;\n // console.log(`${lc} alphabet: ${alphabet}`); // debug\n }\n\n // we now have the alphabet, so find the index of hex character\n // const charIndex = alphabet.indexOf(hexCharFromData);\n const charIndex = getIndex(alphabet, hexCharFromData);\n // console.log(`${lc} charIndex: ${charIndex}`);\n encryptedDataIndexes.push(charIndex);\n }\n\n const encryptedData = encryptedDataIndexes.join(encryptedDataDelimiter);\n return encryptedData;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, getPreHash } from \"../common/encrypt-decrypt-common.mjs\";\nimport { HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Takes a given encryptedData, in the form of a delimited string\n * of indexes, and decrypts it back into encoded hex (not the original\n * unencrypted data!).\n *\n * it does this by iterating\n *\n * @returns unencrypted, but still encoded, hex string of the original unencrypted data\n */\nexport async function decryptToHex_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n}: {\n encryptedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n}): Promise<string> {\n const lc = `[${decryptToHex_stream.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n // console.log(`${lc} first prevHash: ${prevHash}`);\n\n // we have our prevHash starting point, so now we can iterate through the data\n // console.log(`${lc} encryptedDataDelimiter: ${encryptedDataDelimiter}`);\n let encryptedDataIndexes: number[] =\n encryptedData.split(encryptedDataDelimiter).map((nString: string) => parseInt(nString));\n // console.log(`${lc} encryptedDataIndexes: ${encryptedDataIndexes.toString()}`);\n let decryptedDataArray: string[] = [];\n for (let i = 0; i < encryptedDataIndexes.length; i++) {\n // this is the index of the character of data that we want to get\n // out of the alphabet map but to generate the alphabet, we may need\n // to do multiple hash iterations, depending on how big the index\n // is. So if we don't hit a '7' until the third hash, then we need\n // to keep building out the alphabet until that third hash.\n\n // HACK: I'm going to do this with a while loop instead of a for\n // because I want to get it working first.\n\n let charIndex = encryptedDataIndexes[i];\n // console.log(`${lc} charIndex: ${charIndex}`);\n let alphabet: string = \"\";\n let hash: string;\n while (charIndex >= alphabet.length) {\n // console.log(`${lc} doing iteration...`);\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n // console.log(`${lc} alphabet: ${alphabet}`); // debug\n }\n\n // we now have the alphabet, so index into it to get the decrypted hex char\n let hexChar: string = alphabet[charIndex];\n decryptedDataArray.push(hexChar);\n }\n\n // console.log(`${lc} decryptedDataArray: ${decryptedDataArray.toString()}`);\n // reconstitute the decryptedHex\n const decryptedHex: string = decryptedDataArray.join('');\n // console.log(`${lc} decryptedHex: ${decryptedHex.toString()}`);\n return decryptedHex;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from '../constants.mjs';\nimport { decodeHexStringToString } from '../helper.mjs';\nimport { DecryptArgs, DecryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { decryptToHex_stream } from './decrypt-to-hex-stream-mode.mjs';\n\n/**\n * Does the actual decryption work using the original stream code.\n *\n * I'm trying to change this as little as possible for reference and sanity\n * checks.\n *\n * {@link decrypt}\n * {@link DecryptArgs}\n * {@link DecryptResult}\n *\n * @returns a `DecryptResult` info object\n */\nexport async function decryptImpl_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n}: DecryptArgs): Promise<DecryptResult> {\n const lc = `[${decryptImpl_stream.name}]`;\n // console.log(`${lc} encryptedDataDelimiter: ${encryptedDataDelimiter}`);\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // #region set args defaults\n\n initialRecursions = initialRecursions || c.DEFAULT_INITIAL_RECURSIONS;\n recursionsPerHash = recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n saltStrategy = saltStrategy || c.DEFAULT_SALT_STRATEGY;\n hashAlgorithm = hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n salt = salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n encryptedDataDelimiter = encryptedDataDelimiter || c.DEFAULT_ENCRYPTED_DATA_DELIMITER;\n\n // #endregion\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0`; console.error(e); errors.push(e); }\n if (!encryptedData) { const e = `${lcv} encryptedData required`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required`; console.error(e); errors.push(e); }\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n return {\n errors,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n }\n }\n\n // #endregion\n\n // decrypt from indices into hex\n // console.log(`${lc} encryptedData: ${encryptedData}`);\n let hexEncodedData: string = await decryptToHex_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n });\n\n // console.log(`${lc} hexEncodedData: ${hexEncodedData}`);\n // decode hex back into original data\n const decryptedData: string = await decodeHexStringToString(hexEncodedData);\n\n return {\n decryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from '../constants.mjs';\nimport { decodeHexStringToString, encodeStringToHexString } from '../helper.mjs';\nimport { ALPHABET_INDEXING_MODES, EncryptArgs, EncryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { encryptFromHex_stream } from './encrypt-from-hex-stream-mode.mjs';\nimport { decryptImpl_stream } from './decrypt-stream-mode.mjs';\n\n/**\n * Does the actual encryption work using the original \"stream\" streaming\n * encryption.\n *\n * {@link encrypt}\n * {@link EncryptArgs}\n * {@link EncryptResult}\n *\n * @returns a `EncryptResult` info object\n */\nexport async function encryptImpl_stream({\n dataToEncrypt,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n confirm,\n indexingMode,\n}: EncryptArgs): Promise<EncryptResult> {\n const lc = `[${encryptImpl_stream.name}]`;\n\n const errors: string[] = [];\n let warnings: string[] = [];\n\n // #region set args defaults\n\n if (!initialRecursions) {\n console.warn(`${lc} initial recursions required. defaulting to ${c.DEFAULT_INITIAL_RECURSIONS}`);\n initialRecursions = c.DEFAULT_INITIAL_RECURSIONS;\n }\n recursionsPerHash = recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n saltStrategy = saltStrategy || c.DEFAULT_SALT_STRATEGY;\n hashAlgorithm = hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n salt = salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n encryptedDataDelimiter = encryptedDataDelimiter || c.DEFAULT_ENCRYPTED_DATA_DELIMITER;\n indexingMode = indexingMode || c.DEFAULT_ALPHABET_INDEXING_MODE_LEGACY;\n\n // #endregion\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0`; console.error(e); errors.push(e); }\n if (!dataToEncrypt) { const e = `${lcv} dataToEncrypt required`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required`; console.error(e); errors.push(e); }\n if (!ALPHABET_INDEXING_MODES.includes(indexingMode)) { const e = `${lcv} invalid indexingMode (${indexingMode}). Must be one of ${ALPHABET_INDEXING_MODES} (E: 5955c46755434982982823c97adcf076)`; console.error(e); errors.push(e); }\n\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n return {\n errors,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n }\n }\n\n // #endregion\n\n // #region encode data to just hex (i.e. only have 0-9, a-f)\n\n // console.log(`${lc} hex encoding dataToEncrypt: ${dataToEncrypt}`);\n const hexEncodedData: string = await encodeStringToHexString(dataToEncrypt);\n if (confirm) {\n // confirm data can be converted back into the original data\n // console.log(`${lc} hex decoding back to check with dataToEncrypt: ${hexEncodedData}`);\n const confirmDecodedData = await decodeHexStringToString(hexEncodedData);\n // console.log(`${lc} checkDecodedData: ${confirmDecodedData}`);\n if (confirmDecodedData !== dataToEncrypt) {\n throw new Error(`decoding encoded hex failed for this data: The encoded hex did not reverse to the original data.`);\n }\n }\n\n // #endregion\n\n // #region encrypt hex\n\n // comma-delimited indexes string\n let encryptedData: string = await encryptFromHex_stream({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode: 'indexOf',\n });\n\n if (confirm) {\n const resDecrypt = await decryptImpl_stream({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n });\n if ((resDecrypt.errors || []).length > 0) {\n return {\n errors: [`Confirm check found that decrypt had errors.`, ...resDecrypt.errors!],\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n };\n } else if (!resDecrypt.decryptedData) {\n throw new Error(`Confirm check call to decrypt produced falsy decryptedData`);\n } else if (resDecrypt.decryptedData !== dataToEncrypt) {\n // DO NOT LEAVE THIS IN PROD!!!\n // console.log(`resDecrypt.decryptedData: ${resDecrypt.decryptedData}`); // DO NOT LEAVE THIS IN PROD!!!\n // console.log(`dataToEncrypt: ${dataToEncrypt}`); // DO NOT LEAVE THIS IN PROD!!!\n // DO NOT LEAVE THIS IN PROD!!!\n throw new Error(`The ENCRYPTED data did not decrypt back to the original data.`);\n } else {\n // console.log(`${lc} decrypt confirmed.`);\n }\n if ((resDecrypt.warnings || []).length > 0) {\n warnings = warnings.concat([`Confirm check call to decrypt had warnings.`, ...resDecrypt.warnings!])\n }\n }\n\n // #endregion\n\n return {\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n hashAlgorithm,\n encryptedDataDelimiter,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, } from \"../common/encrypt-decrypt-common.mjs\";\nimport { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n// import { ENCRYPT_LOG_A_LOT } from '../constants.mjs';\n// const logalot = ENCRYPT_LOG_A_LOT || true;\n\n/**\n * Internal function that performs the encryption part of the overall `encrypt`\n * function when using the `multipass` option.\n *\n * @returns ciphertext string\n */\nexport async function encryptFromHex_blockMode({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n maxBlockSize,\n numOfPasses,\n}: {\n hexEncodedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n indexingMode: AlphabetIndexingMode,\n maxBlockSize: number,\n numOfPasses: number,\n}): Promise<string> {\n const lc = `[${encryptFromHex_blockMode.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n // console.warn(`${lc} first prevHash: ${prevHash}`);\n // if (logalot) { console.warn(`${lc} doInitialRecursions_keystretch result prevHash: ${prevHash} (W: 0a7979f8f0c6193e7a68d9573143e423)`); }\n\n /**\n * closure for avoiding checking `indexingMode` in a tight loop.\n *\n * usually I don't go for early optimization but this is low hanging\n * fruit in a very tight loop.\n */\n const getIndexOfCharInAlphabet: (alphabet: string, hexChar: string) => number =\n indexingMode === 'indexOf' ?\n (alphabet: string, hexChar: string) => { return alphabet.indexOf(hexChar) } :\n (alphabet: string, hexChar: string) => { return alphabet.lastIndexOf(hexChar) };\n // if (logalot) { console.warn(`${lc} using getIndexOfCharInAlphabet (indexingMode: ${indexingMode})`); }\n\n /**\n * ultimate indexes that will be stored in output.\n *\n * The index into this array corresponds to the index into\n * `hexEncodedData` array (`indexData`).\n */\n let encryptedDataIndexes: number[] = [];\n\n // set the initial pass length.\n let totalLength = hexEncodedData.length;\n let blockSize = maxBlockSize;\n if (blockSize > totalLength) { blockSize = totalLength; }\n // if (logalot) { console.warn(`${lc} totalLength (hexEncodedData.length): ${totalLength}, blockSize: ${blockSize} (W: 1529570c6b474ad1a24f3a4c5b7eceb0)`); }\n\n /**\n * We are doing multiple passes, but possibly only on subsets of\n * hexEncodedData. This variable is the number of sections that we're\n * doing. The final section may be less than a full pass section.\n *\n * _note: I am avoiding the use of \"block\" since that is an overloaded term in cryptography._\n */\n let blockSections = Math.ceil(totalLength / blockSize);\n // if (logalot) { console.warn(`${lc} blockSections: ${blockSections}`); }\n /**\n * the final pass may be less than the pass length.\n */\n // let finalBlockSize = (blockSize - ((blockSections * blockSize) - totalLength)) || blockSize; // if 0, then the last pass is full length\n let finalBlockSize = (totalLength % blockSize) || blockSize; // if 0, then the last pass is full length\n // if (logalot) { console.warn(`${lc} finalBlockSize: ${finalBlockSize}`); }\n /**\n * index into hexEncodedData at the start of each pass.\n *\n * This will be adjusted after each pass in the loop in preparation for\n * next iteration.\n */\n let indexHexEncodedDataAtStartOfPass = 0;\n\n // iterate through each pass \"section\" and create the alphabets for the\n // entire section. once the alphabets are created, iterate the plaintext\n // hexEncodedData and map them to the indices into those alphabets.\n // todo: add parameterized step to encode indices into characters?\n for (let indexOfBlock = 0; indexOfBlock < blockSections; indexOfBlock++) {\n\n // adjust the blockSize if it's the final one which might be shorter\n const isFinalBlock = indexOfBlock === blockSections - 1;\n if (isFinalBlock) { blockSize = finalBlockSize; }\n // if (logalot) { console.warn(`${lc} blockSize: ${blockSize}`); }\n\n const resGetAlphabets = await getAlphabetsThisBlock({\n blockSize,\n indexHexEncodedDataAtStartOfPass,\n numOfPasses,\n hexEncodedData,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n });\n\n let alphabetsThisBlock = resGetAlphabets.alphabetsThisBlock;\n // if (logalot) { console.warn(`${lc} alphabetsThisBlock: ${pretty(alphabetsThisBlock)} (W: 8c37818b9658d4c6a418b62ec38bd923)`); }\n prevHash = resGetAlphabets.prevHash;\n // if (logalot) { console.warn(`${lc} prevHash after alphabets created: ${prevHash} (W: 0b2ffc3ba7a19ecba74fcec8788a6c23)`); }\n\n const encryptedIndexesThisBlock = await getEncryptedIndexesThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexHexEncodedDataAtStartOfPass,\n hexEncodedData,\n getIndexOfCharInAlphabet,\n });\n\n // if (logalot) { console.warn(`${lc} encryptedIndexesThisBlock: ${encryptedIndexesThisBlock} (W: f84c9d05e4160241664051b946ad3f23)`); }\n\n // if (logalot) { console.warn(`${lc} info before add to encryptedDataIndexes info: ${pretty({ indexOfBlock, isFinalBlock, blockSize, prevHash, encryptedDataIndexes, encryptedIndexesThisBlock })}`); }\n encryptedDataIndexes = encryptedDataIndexes.concat(encryptedIndexesThisBlock);\n // if (logalot) { console.warn(`${lc} encryptedDataIndexes so far: ${encryptedDataIndexes} (W: 58f9bbabce8eeb90a213ab1fa0d88123)`); }\n\n indexHexEncodedDataAtStartOfPass += blockSize;\n }\n\n // we now have populated encryptedDataIndexes fully.\n const resEncryptedData = encryptedDataIndexes.join(encryptedDataDelimiter);\n // if (logalot) { console.warn(`${lc} final resEncryptedData: ${resEncryptedData} (W: 681bf4eccdf6cddf675ee608804a7e23)`); }\n // console.warn(`${lc} resEncryptedData: ${resEncryptedData}`);\n return resEncryptedData;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nasync function getAlphabetsThisBlock({\n blockSize,\n numOfPasses,\n indexHexEncodedDataAtStartOfPass,\n hexEncodedData,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n}: {\n /** size of the pass, i.e. number of characters to process */\n blockSize: number,\n /** number of times to iterate over the pass section */\n numOfPasses: number,\n indexHexEncodedDataAtStartOfPass: number,\n hexEncodedData: string,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n prevHash: string,\n hashAlgorithm: HashAlgorithm,\n}): Promise<{ alphabetsThisBlock: string[], prevHash: string }> {\n const lc = `[${getAlphabetsThisBlock.name}]`;\n try {\n // if (logalot) { console.warn(`${lc} info: ${pretty({ blockSize, numOfPasses, indexHexEncodedDataAtStartOfPass, prevHash })}`); }\n /**\n * one alphabet per plaintext character (hex only atow).\n *\n * index into this is index in this pass (`indexPass`).\n *\n * Instead of building each plaintext character's alphabet until at\n * least one instance of that character is found, we will build up\n * each of the alphabets for the entire pass. Then we will add on to\n * those alphabets, depending on if the character is found (and once\n * I implement it, additionalSuperfluousAlphabetExtensions).\n */\n let alphabetsThisBlock: string[] = [];\n /** index into the `hexEncodedData` that we're working with */\n let indexHexEncodedData: number;\n let hash: string;\n // first construct all alphabets for this pass section using the\n // given number of passes. Note that zero or more of these alphabets\n // may NOT include the hex character to encode, but this will be\n // addressed in the next step.\n for (let passNum = 0; passNum < numOfPasses; passNum++) {\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexHexEncodedData = indexHexEncodedDataAtStartOfPass + indexIntoBlock;\n // if (logalot) { console.warn(`${lc} passNum: ${passNum}, indexIntoBlock: ${indexIntoBlock} (W: 13d09af12647907d4497842616915223)`); }\n let alphabet = alphabetsThisBlock[indexIntoBlock] ?? '';\n\n // if (logalot) { console.warn(`${lc} starting alphabet: ${alphabet} (W: b5a3ba3203e679ac454a854c32846723)`); }\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n // if (logalot) { console.warn(`${lc} extended alphabet: ${alphabet} (W: c0228b716a324761b581d38a805d192b)`); }\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n // if (logalot) { console.warn(`${lc} alphabetsThisBlock: ${pretty(alphabetsThisBlock)} (W: 1bef26a111a4df4a6d501d5a662dd223)`); }\n }\n }\n // if (logalot) { console.warn(`${lc} initial alphabetsThisBlock (${alphabetsThisBlock.length}): ${pretty(alphabetsThisBlock)} (W: ce1f77a7065e45cfb12995f097f70af4)`); }\n\n // if (logalot) { console.warn(`${lc} at this point, each alphabet is the same size (numOfPasses * hash size), but it's not guaranteed that each alphabet will contain the plaintext character. so go through and extend any alphabets that do not yet contain the plaintext character (I: c75085603497ea684865010dfd8a3b23)`); }\n\n // at this point, each alphabet is the same size (numOfPasses * hash\n // size), but it's not guaranteed that each alphabet will contain the\n // plaintext character. so go through and extend any alphabets that do\n // not yet contain the plaintext character\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexHexEncodedData = indexHexEncodedDataAtStartOfPass + indexIntoBlock;\n const hexCharFromData: string = hexEncodedData[indexHexEncodedData];\n let alphabet = alphabetsThisBlock[indexIntoBlock];\n\n while (!alphabet.includes(hexCharFromData)) {\n // if (logalot) { console.warn(`${lc} alphabet (${alphabet}) has to be extended because it does not contain hexChar (${hexCharFromData}). (W: a8040eb78f4d123cfa423de33a7f3b23)`); }\n // only executes if alphabet doesnt already contain hexChar\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash!;\n prevHash = hash;\n }\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n // if (logalot) { console.warn(`${lc} alphabetsThisBlock (length ${alphabetsThisBlock.length}): ${pretty(alphabetsThisBlock)} (W: a86e76aa398d7e4b44dbe0fbb79c1623)`); }\n }\n // if (logalot) { console.warn(`${lc} guaranteed alphabetsThisBlock (${alphabetsThisBlock.length}): ${pretty(alphabetsThisBlock)} (W: 8d684c05b116467aa92e946b03160310)`); }\n\n // if (logalot) { console.warn(`${lc} at this point, each alphabet is at least the minimum size and is guaranteed to have at least once instance of the plaintext hexChar. (W: c6f31445402b1c561670a2dd59530523)`); }\n // at this point, each alphabet is at least the minimum size and is\n // guaranteed to have at least once instance of the plaintext hexChar.\n // if (logalot) { console.warn(`${lc} return prevHash: ${prevHash}`) }\n return { alphabetsThisBlock, prevHash };\n } catch (error) {\n console.error(`${lc} error: ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nasync function getEncryptedIndexesThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexHexEncodedDataAtStartOfPass,\n hexEncodedData,\n getIndexOfCharInAlphabet,\n}: {\n alphabetsThisBlock: string[],\n blockSize: number,\n indexHexEncodedDataAtStartOfPass: number,\n hexEncodedData: string,\n getIndexOfCharInAlphabet: (alphabet: string, hexChar: string) => number,\n}): Promise<number[]> {\n const lc = `[${getEncryptedIndexesThisBlock.name}]`;\n try {\n const resIndexes: number[] = [];\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n const indexHexEncodedData = indexHexEncodedDataAtStartOfPass + indexIntoBlock;\n const alphabet = alphabetsThisBlock[indexIntoBlock];\n const encryptedIndexIntoAlphabet = getIndexOfCharInAlphabet(alphabet, hexEncodedData[indexHexEncodedData]);\n resIndexes.push(encryptedIndexIntoAlphabet);\n }\n\n return resIndexes;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { doInitialRecursions_keystretch, execRound_getNextHash, getPreHash } from \"../common/encrypt-decrypt-common.mjs\";\nimport { AlphabetIndexingMode, HashAlgorithm, SaltStrategy } from \"../types.mjs\";\n\n/**\n * Internal function that takes a given encryptedData, in the form of a\n * delimited string of indexes, and decrypts it back into encoded hex (not the\n * original unencrypted data!).\n *\n * It does this by reconstructing the JIT alphabets for each section, just as\n * was done in the encrypting process. It then uses the encrypted indexes into\n * these alphabets and rebuilds the multipass section's plaintext **hex**.\n *\n * For documentation on args, see `DecryptArgs`.\n *\n * @returns unencrypted, but still hex-encoded plaintext string\n */\nexport async function decryptToHex_blockMode({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n maxBlockSize,\n numOfPasses,\n}: {\n encryptedData: string,\n initialRecursions: number,\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n secret: string,\n hashAlgorithm: HashAlgorithm,\n encryptedDataDelimiter: string,\n maxBlockSize: number,\n numOfPasses: number,\n}): Promise<string> {\n const lc = `[${decryptToHex_blockMode.name}]`;\n\n try {\n // set up \"prevHash\" as a starting point, similar to key-stretching\n let prevHash = await doInitialRecursions_keystretch({\n secret,\n initialRecursions,\n salt,\n saltStrategy: saltStrategy!,\n hashAlgorithm: hashAlgorithm!,\n });\n\n // we have our prevHash starting point, so now we can iterate through the data\n let encryptedDataIndexes: number[] =\n encryptedData.split(encryptedDataDelimiter).map((nString: string) => parseInt(nString));\n let decryptedDataArray: string[] = [];\n\n // re-play multipass building of alphabets. Section by section, first\n // create the minimum number of alphabets. Then iterate through each\n // cipher index, extending individual alphabets JIT/on demand depending\n // on the cipher index, i.e., if the index is larger than the existing\n // alphabet, then we extend it another round.\n\n // set the initial pass length.\n let totalLength = encryptedDataIndexes.length;\n let blockSize = maxBlockSize;\n if (blockSize > totalLength) { blockSize = totalLength; }\n\n /**\n * We are doing multiple passes, but possibly only on subsets of\n * encryptedDataIndexes. This variable is the number of sections that we're\n * doing. The final section may be less than a full pass section.\n *\n * _note: I am avoiding the use of \"block\" since that is an overloaded term in cryptography and is usually related to padding._\n */\n let blockSections = Math.ceil(totalLength / blockSize);\n /**\n * the final pass may be less than the pass length.\n */\n let finalBlockSize = (totalLength % blockSize) || blockSize; // if 0, then the last pass is full length\n /**\n * index into encryptedDataIndexes at the start of each pass.\n *\n * This will be adjusted after each pass in the loop in preparation for\n * next iteration.\n */\n let indexEncryptedDataIndexesAtStartOfPass = 0;\n\n // iterate through each pass \"section\" and create the alphabets for the\n // entire section. once the alphabets are created, iterate the plaintext\n // hexEncodedData and map them to the indices into those alphabets.\n // todo: add parameterized step to encode indices into characters?\n for (let indexOfBlock = 0; indexOfBlock < blockSections; indexOfBlock++) {\n\n // adjust the blockSize if it's the final one which might be shorter\n const isFinalBlock = indexOfBlock === blockSections - 1;\n if (isFinalBlock) { blockSize = finalBlockSize; }\n\n const resGetAlphabets = await getAlphabetsThisBlock({\n blockSize,\n indexEncryptedDataIndexesAtStartOfPass,\n numOfPasses,\n encryptedDataIndexes,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n });\n\n let alphabetsThisBlock = resGetAlphabets.alphabetsThisBlock;\n prevHash = resGetAlphabets.prevHash; // used in next section if there is one\n\n const decryptedDataArrayThisBlock = await getDecryptedDataArrayThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexEncryptedDataIndexesAtStartOfPass,\n encryptedDataIndexes,\n });\n\n decryptedDataArray = decryptedDataArray.concat(decryptedDataArrayThisBlock);\n\n indexEncryptedDataIndexesAtStartOfPass += blockSize;\n }\n\n // reconstitute the decryptedHex\n const decryptedHex: string = decryptedDataArray.join('');\n return decryptedHex;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * internal function that builds the JIT alphabets for a given multipass\n * section.\n *\n * @returns alphabetsThisBlock array of alphabets and the final `prevHash` for use in the next multipass section (if any).\n */\nasync function getAlphabetsThisBlock({\n blockSize,\n numOfPasses,\n indexEncryptedDataIndexesAtStartOfPass,\n encryptedDataIndexes,\n recursionsPerHash,\n salt,\n saltStrategy,\n prevHash,\n hashAlgorithm,\n}: {\n /**\n * Size of the multipass section, i.e. number of characters to\n * encrypt/decrypt as a whole.\n */\n blockSize: number,\n /**\n * Number of times to iterate over the multipass section\n */\n numOfPasses: number,\n indexEncryptedDataIndexesAtStartOfPass: number,\n encryptedDataIndexes: number[],\n recursionsPerHash: number,\n salt: string,\n saltStrategy: SaltStrategy,\n prevHash: string,\n hashAlgorithm: HashAlgorithm,\n}): Promise<{ alphabetsThisBlock: string[], prevHash: string }> {\n const lc = `[${getAlphabetsThisBlock.name}]`;\n try {\n /**\n * one alphabet per plaintext character (hex only atow).\n *\n * index into this is index in this pass (`indexPass`).\n *\n * Instead of building each plaintext character's alphabet until at\n * least one instance of that character is found, we will build up\n * each of the alphabets for the entire pass. Then we will add on to\n * those alphabets, depending on if the character is found (and once\n * I implement it, additionalSuperfluousAlphabetExtensions).\n */\n let alphabetsThisBlock: string[] = [];\n /** index into the `encryptedDataIndexes` that we're working with */\n let indexEncryptedDataIndexes: number;\n let hash: string;\n // first construct all alphabets for this pass section using the\n // given number of passes. Note that zero or more of these alphabets\n // may NOT include the hex character to encode, but this will be\n // addressed in the next step.\n for (let passNum = 0; passNum < numOfPasses; passNum++) {\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexEncryptedDataIndexes = indexEncryptedDataIndexesAtStartOfPass + indexIntoBlock;\n let alphabet = alphabetsThisBlock[indexIntoBlock] ?? '';\n\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n }\n }\n\n // at this point, each alphabet is the same size (numOfPasses * hash\n // size), but it's not guaranteed that each alphabet will contain the\n // plaintext character. so go through and extend any alphabets that do\n // not yet contain the plaintext character\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n indexEncryptedDataIndexes = indexEncryptedDataIndexesAtStartOfPass + indexIntoBlock;\n const encryptedIndex: number = encryptedDataIndexes[indexEncryptedDataIndexes];\n let alphabet = alphabetsThisBlock[indexIntoBlock];\n\n // while (!alphabet.includes(hexCharFromData)) {\n while (alphabet.at(encryptedIndex) === undefined) {\n // only executes if alphabet isn't long enough for index\n hash = await execRound_getNextHash({\n count: recursionsPerHash,\n prevHash, salt, saltStrategy, hashAlgorithm\n });\n alphabet += hash;\n prevHash = hash;\n }\n\n alphabetsThisBlock[indexIntoBlock] = alphabet;\n }\n\n // at this point, each alphabet is at least the minimum size and is\n // guaranteed to have at least once instance of the plaintext hexChar.\n return { alphabetsThisBlock, prevHash };\n } catch (error) {\n console.error(`${lc} error: ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Takes the incoming encrypted indexes for a multipass section and maps them to\n * plaintext.\n *\n * @param args see individual param docs\n * @returns plaintext as an array of strings\n */\nasync function getDecryptedDataArrayThisBlock({\n alphabetsThisBlock,\n blockSize,\n indexEncryptedDataIndexesAtStartOfPass,\n encryptedDataIndexes,\n}: {\n /**\n * All alphabets for this multipass section that we have already created in\n * a previous step.\n */\n alphabetsThisBlock: string[],\n /**\n * Size of the multipass section that we are processing as a whole.\n */\n blockSize: number,\n /**\n * Start of the multipass section, used to index into {@link encryptedDataIndexes}.\n */\n indexEncryptedDataIndexesAtStartOfPass: number,\n /**\n * Reference to the entire encrypted data array.\n *\n * We will index into this array and get the \"encrypted data index\" which is\n * the index into the alphabet for that encrypted character.\n */\n encryptedDataIndexes: number[],\n}): Promise<string[]> {\n const lc = `[${getDecryptedDataArrayThisBlock.name}]`;\n try {\n const resDataArray: string[] = [];\n\n for (let indexIntoBlock = 0; indexIntoBlock < blockSize; indexIntoBlock++) {\n let indexEncryptedDataIndexes = indexEncryptedDataIndexesAtStartOfPass + indexIntoBlock;\n const encryptedIndex: number = encryptedDataIndexes[indexEncryptedDataIndexes];\n let alphabet = alphabetsThisBlock[indexIntoBlock];\n let decryptedCharString = alphabet[encryptedIndex];\n resDataArray.push(decryptedCharString);\n }\n\n return resDataArray;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from '../constants.mjs';\nimport { decodeHexStringToString } from '../helper.mjs';\nimport { ALPHABET_INDEXING_MODES, DecryptArgs, DecryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { decryptToHex_blockMode } from './decrypt-to-hex-block-mode.mjs';\n\n/**\n * Does the actual decryption work using shortCircuit mitigation strategies.\n *\n// * {@link decrypt}\n * {@link DecryptArgs}\n * {@link DecryptResult}\n *\n * @returns a `DecryptResult` info object\n */\nexport async function decryptImpl_blockMode(args: DecryptArgs): Promise<DecryptResult> {\n const lc = `[${decryptImpl_blockMode.name}]`;\n let {\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n blockMode,\n multipass,\n } = args;\n\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (blockMode && multipass) { throw new Error(`blockMode and multipass set. blockMode was a refactored name of multipass, so these should not both be present. multipass is deprecated. (E: b9b3cd1f701c700835c0419260278223)`); }\n if (!blockMode && !!multipass) {\n console.warn(`${lc}[WARNING] \"multipass\" option is deprecated. this has been refactored to \"blockMode\". This will use multipass as blockMode. (W: b77c9773e30549cbb389ce61f31eb6d3)`);\n blockMode = multipass; // to support older versions that use refactored \"multipass\"\n }\n if (!blockMode) { throw new Error(`(UNEXPECTED) blockMode required. This should be truthy in order to get to this impl fn. (E: 306bce36afd64b7182ca2b46ac04a261)`); }\n\n // #region set args defaults\n\n initialRecursions = initialRecursions || c.DEFAULT_INITIAL_RECURSIONS;\n recursionsPerHash = recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n saltStrategy = saltStrategy || c.DEFAULT_SALT_STRATEGY;\n hashAlgorithm = hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n salt = salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n encryptedDataDelimiter = encryptedDataDelimiter || c.DEFAULT_ENCRYPTED_DATA_DELIMITER;\n\n indexingMode = indexingMode || c.DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE;\n\n let { maxBlockSize, maxPassSectionLength, numOfPasses } = blockMode;\n if (!maxBlockSize && !!maxPassSectionLength) {\n console.warn(`${lc}[WARNING] \"maxPassSectionLength\" option is deprecated. this has been refactored to \"maxBlockSize\". This will use maxPassSectioLength as maxBlockSize. (W: e2c83d78a3464704a6067e0f767f20b0)`);\n maxBlockSize = maxPassSectionLength;\n }\n maxBlockSize = maxBlockSize || c.DEFAULT_MAX_BLOCK_SIZE;\n numOfPasses = numOfPasses || c.DEFAULT_NUM_OF_PASSES;\n\n // #endregion\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0`; console.error(e); errors.push(e); }\n if (!encryptedData) { const e = `${lcv} encryptedData required`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required`; console.error(e); errors.push(e); }\n if (!indexingMode) { const e = `${lcv} indexingMode required (E: a6fe15f8ba414e21b5355d23e808b976)`; console.error(e); errors.push(e); }\n if (!ALPHABET_INDEXING_MODES.includes(indexingMode)) { const e = `${lcv} invalid indexingMode (${indexingMode}). Must be one of ${ALPHABET_INDEXING_MODES} (E: 17435268651444e0b7a594135635fc58)`; console.error(e); errors.push(e); }\n if (maxBlockSize < 1) { const e = `${lcv} maxBlockSize must be greater than 0 (E: 0870831aa86b4bfa939aeee9f252326a)`; console.error(e); errors.push(e); }\n if (numOfPasses < 1) { const e = `${lcv} numOfPasses must be greater than 0 (E: 691d3c3765584c6f8c9aba1ee378df00)`; console.error(e); errors.push(e); }\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n let result = { ...args, errors: errors };\n delete (result as any).encryptedData;\n delete (result as any).secret;\n return result;\n }\n\n // #endregion args validation\n\n // decrypt from indices into hex\n let hexEncodedData: string = await decryptToHex_blockMode({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n maxBlockSize,\n numOfPasses,\n });\n\n // decode hex back into original data\n const decryptedData: string = await decodeHexStringToString(hexEncodedData);\n\n const result: DecryptResult = {\n ...args,\n decryptedData,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n delete (result as any).encryptedData;\n delete (result as any).secret;\n return result;\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { decodeHexStringToString, encodeStringToHexString } from '../helper.mjs';\nimport { ALPHABET_INDEXING_MODES, EncryptArgs, EncryptResult, HashAlgorithm, SALT_STRATEGIES } from \"../types.mjs\";\nimport { encryptFromHex_blockMode } from './encrypt-from-hex-block-mode.mjs';\nimport { decryptImpl_blockMode } from './decrypt-block-mode.mjs';\nimport {\n DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE,\n DEFAULT_ENCRYPTED_DATA_DELIMITER, DEFAULT_INITIAL_RECURSIONS,\n DEFAULT_MAX_BLOCK_SIZE, DEFAULT_NUM_OF_PASSES,\n ENCRYPT_LOG_A_LOT\n} from '../constants.mjs';\n\n// const logalot = ENCRYPT_LOG_A_LOT || true;\n\n/**\n * Does the actual encryption work using the original \"stream\" streaming\n * encryption.\n *\n * {@link encrypt}\n * {@link EncryptArgs}\n * {@link EncryptResult}\n *\n * @returns a `EncryptResult` info object\n */\nexport async function encryptImpl_blockMode(args: EncryptArgs): Promise<EncryptResult> {\n const lc = `[${encryptImpl_blockMode.name}]`;\n\n let {\n dataToEncrypt,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n confirm,\n indexingMode,\n blockMode,\n multipass,\n } = args;\n\n const errors: string[] = [];\n let warnings: string[] = [];\n\n if (blockMode && multipass) { throw new Error(`blockMode and multipass set. blockMode was a refactored name of multipass, so these should not both be present. multipass is deprecated. (E: bde5efd1a3e449dca549c5bff147f09b)`); }\n if (!blockMode && !!multipass) {\n console.warn(`${lc}[WARNING] \"multipass\" option is deprecated. this has been refactored to \"blockMode\". This will use multipass as blockMode. (W: 046b55a6d1304155b2e5352a9e6140b0)`);\n blockMode = multipass; // to support older versions that use refactored \"multipass\"\n }\n if (!blockMode) { throw new Error(`(UNEXPECTED) blockMode required. This should be truthy in order to get to this impl fn. (E: 0b87871f81d849ef8f0263b7775bd3e3)`); }\n\n // #region set args defaults\n\n if (!initialRecursions) {\n console.warn(`${lc} initial recursions required. defaulting to ${DEFAULT_INITIAL_RECURSIONS}`);\n initialRecursions = DEFAULT_INITIAL_RECURSIONS;\n }\n encryptedDataDelimiter = encryptedDataDelimiter || DEFAULT_ENCRYPTED_DATA_DELIMITER;\n indexingMode = indexingMode || DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE;\n\n // let { maxPassSectionLength, numOfPasses } = blockMode;\n // maxPassSectionLength = maxPassSectionLength || DEFAULT_MAX_BLOCK_SIZE;\n // numOfPasses = numOfPasses || DEFAULT_NUM_OF_PASSES;\n let { maxBlockSize, maxPassSectionLength, numOfPasses } = blockMode;\n if (!maxBlockSize && !!maxPassSectionLength) {\n console.warn(`${lc}[WARNING] \"maxPassSectionLength\" option is deprecated. this has been refactored to \"maxBlockSize\". This will use maxPassSectioLength as maxBlockSize. (W: c28fe476105643e184d0ddd5d2aa8a5d)`);\n maxBlockSize = maxPassSectionLength;\n }\n maxBlockSize = maxBlockSize || DEFAULT_MAX_BLOCK_SIZE;\n numOfPasses = numOfPasses || DEFAULT_NUM_OF_PASSES;\n\n // #endregion set args defaults\n\n // #region args validation\n\n const lcv = `[validation]`;\n\n if (!initialRecursions || initialRecursions < 1) { const e = `${lcv} initialRecursions required, and greater than 0 (E: dd96a75f0c504f34b1f9f2f32e011c50)`; console.error(e); errors.push(e); }\n if (!recursionsPerHash || recursionsPerHash < 1) { const e = `${lcv} recursionsPerHash required, and greater than 0 (E: 64cf53e0bf9f4963be6b165ca4e6566d)`; console.error(e); errors.push(e); }\n if (!salt) { const e = `${lcv} salt required (E: 136a5d237e0f4b1d89f8c87ac12a1507)`; console.error(e); errors.push(e); }\n if (!saltStrategy) { const e = `${lcv} saltStrategy required (E: 457ed117bf224b9f86fe81ab6bc35381)`; console.error(e); errors.push(e); }\n if (!secret) { const e = `${lcv} secret required (E: 5c363255055a45cfb07656e2f4854ed7)`; console.error(e); errors.push(e); }\n if (!encryptedDataDelimiter) { const e = `${lcv} encryptedDataDelimiter required (E: 1bbeb4dce19e4ac2bbe7d1e373739298)`; console.error(e); errors.push(e); }\n if (!indexingMode) { const e = `${lcv} indexingMode required (E: 693ebd2be64a438aa3b075d0cb0d92bf)`; console.error(e); errors.push(e); }\n if (!ALPHABET_INDEXING_MODES.includes(indexingMode)) { const e = `${lcv} invalid indexingMode (${indexingMode}). Must be one of ${ALPHABET_INDEXING_MODES} (E: 17435268651444e0b7a594135635fc58)`; console.error(e); errors.push(e); }\n if (maxBlockSize < 1) { const e = `${lcv} maxBlockSize must be greater than 0 (E: 9f268207ae274b958fb91855331be259)`; console.error(e); errors.push(e); }\n if (numOfPasses < 1) { const e = `${lcv} numOfPasses must be greater than 0 (E: c3bcab79bb024d65b84947806290a7d4)`; console.error(e); errors.push(e); }\n\n // if (hashAlgorithm !== 'SHA-256') { const e = `${lcv} only SHA-256 implemented`; console.error(e); errors.push(e); }\n if (!Object.values(HashAlgorithm).includes(hashAlgorithm!)) {\n const e = `${lcv} only ${Object.values(HashAlgorithm)} hash algorithms implemented`; console.error(e); errors.push(e);\n }\n\n if (saltStrategy && !SALT_STRATEGIES.includes(saltStrategy!)) {\n const e = `${lcv} unknown saltStrategy: ${saltStrategy}`; console.error(e); errors.push(e);\n }\n\n if (errors.length > 0) {\n let result = { ...args, errors: errors };\n delete (result as any).dataToEncrypt;\n delete (result as any).secret;\n return result;\n }\n\n // #endregion args validation\n\n // #region encode data to just hex (i.e. only have 0-9, a-f)\n\n // console.log(`${lc} hex encoding dataToEncrypt: ${dataToEncrypt}`);\n const hexEncodedData: string = await encodeStringToHexString(dataToEncrypt);\n if (confirm) {\n // confirm data can be converted back into the original data\n // console.log(`${lc} hex decoding back to check with dataToEncrypt: ${hexEncodedData}`);\n // if (logalot) { console.log(`${lc} hexEncodedData: ${hexEncodedData} (I: 5568ee9bad6bfaa6f266bc9c5b5fc423)`); }\n const confirmDecodedData = await decodeHexStringToString(hexEncodedData);\n // console.log(`${lc} checkDecodedData: ${confirmDecodedData}`);\n if (confirmDecodedData !== dataToEncrypt) {\n throw new Error(`decoding encoded hex failed for this data: The encoded hex did not reverse to the original data.`);\n }\n }\n\n // #endregion encode data to just hex (i.e. only have 0-9, a-f)\n\n // #region encrypt hex\n\n // comma-delimited indexes string\n const encryptedData: string = await encryptFromHex_blockMode({\n hexEncodedData,\n initialRecursions,\n recursionsPerHash: recursionsPerHash!,\n salt,\n saltStrategy: saltStrategy!,\n secret,\n hashAlgorithm: hashAlgorithm!,\n encryptedDataDelimiter,\n indexingMode,\n maxBlockSize,\n numOfPasses,\n });\n\n // DO NOT LEAVE THIS IN PROD!!!\n // console.warn(`${lc} TAKE THIS OUT!! encryptedData: ${encryptedData}`); // DO NOT LEAVE THIS IN PROD!!!\n // DO NOT LEAVE THIS IN PROD!!!\n\n if (confirm) {\n try {\n const resDecrypt = await decryptImpl_blockMode({\n encryptedData,\n initialRecursions,\n recursionsPerHash,\n salt,\n saltStrategy,\n secret,\n hashAlgorithm,\n encryptedDataDelimiter,\n indexingMode,\n blockMode,\n });\n if (!resDecrypt.decryptedData) {\n throw new Error(`Confirm check call to decrypt produced falsy decryptedData (E: a4fe82dee61f497e9dea188ea9c287a4)`);\n } else if (resDecrypt.decryptedData !== dataToEncrypt) {\n // DO NOT LEAVE THIS IN PROD!!!\n // console.warn(`resDecrypt.decryptedData: ${resDecrypt.decryptedData}`); // DO NOT LEAVE THIS IN PROD!!!\n // console.warn(`dataToEncrypt: ${dataToEncrypt}`); // DO NOT LEAVE THIS IN PROD!!!\n // DO NOT LEAVE THIS IN PROD!!!\n throw new Error(`The ENCRYPTED data did not decrypt back to the original data. (E: 16b5f1a11e4f438ab38a7f124178a7b8)`);\n // } else {\n // console.log(`${lc} decrypt confirmed.`);\n }\n if ((resDecrypt.warnings || []).length > 0) {\n warnings = warnings.concat([`Confirm check call to decrypt had warnings.`, ...resDecrypt.warnings!])\n }\n } catch (error) {\n throw new Error(`${lc} confirm failed. decrypt error: ${extractErrorMsg(error)} (E: 782a84d9dc294ce9a6a325e3ab293adf)`);\n }\n }\n\n // #endregion\n\n const result: EncryptResult = {\n ...args,\n encryptedData,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n delete (result as any).dataToEncrypt;\n delete (result as any).secret;\n return result;\n}\n", "import { getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport * as c from './constants.mjs';\nimport {\n EncryptArgs, EncryptResult,\n DecryptArgs, DecryptResult,\n} from './types.mjs';\nimport { encryptImpl_stream } from './stream-mode/encrypt-stream-mode.mjs'\nimport { encryptImpl_blockMode } from './block-mode/encrypt-block-mode.mjs';\nimport { decryptImpl_stream } from './stream-mode/decrypt-stream-mode.mjs';\nimport { decryptImpl_blockMode } from './block-mode/decrypt-block-mode.mjs';\n\n/**\n * Encrypts given `dataToEncrypt` using the secret and other\n * given algorithm parameters.\n *\n * NOTE: These parameters must be the same when the call to `decrypt` happens!\n *\n * @see {@link DecryptArgs}\n * @see {@link DecryptResult}\n *\n * @returns `EncryptResult` info object with either `dataToEncrypt` or a populated `errors` array.\n */\nexport async function encrypt(args: EncryptArgs): Promise<EncryptResult> {\n const lc = `[${encrypt.name}]`;\n try {\n // initial common validation\n if (!args) { throw new Error('args required (E: 22e58e03c78f4c27bf18295b8d2cdd3a)'); }\n if (!args.dataToEncrypt) { throw new Error(`dataToEncrypt required (E: 168c9076e5434c83ba81e3485ee6f3e4)`); }\n\n // common defaults\n args.salt = args.salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n args.saltStrategy = args.saltStrategy || c.DEFAULT_SALT_STRATEGY;\n args.hashAlgorithm = args.hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n args.recursionsPerHash = args.recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n\n // route to appropriate implementor\n let result: EncryptResult;\n if (args.blockMode) {\n result = await encryptImpl_blockMode(args);\n } else {\n result = await encryptImpl_stream(args);\n }\n\n // print out warnings/errors if necessary\n if ((result.errors ?? []).length > 0) { result.errors!.forEach(e => console.warn(`${lc} ${e}`)); }\n if ((result.warnings ?? []).length > 0) { result.warnings!.forEach(w => console.warn(`${lc} ${w}`)); }\n\n // we're done\n return result;\n } catch (error) {\n console.error(`${lc}${error.message}`);\n throw error;\n // const result = { ...args, errors: [error] };\n // delete (result as any).dataToEncrypt;\n // delete (result as any).secret;\n // return result;\n }\n}\n\n/**\n * Decrypts given `encryptedData` using the secret and other\n * given algorithm parameters.\n *\n * NOTE: These parameters must be the same as what the `encrypt` call used!\n *\n * @see {@link DecryptArgs}\n * @see {@link DecryptResult}\n *\n * @returns `DecryptResult` info object with either `decryptedData` or a populated `errors` array.\n */\nexport async function decrypt(args: DecryptArgs): Promise<DecryptResult> {\n const lc = `[${decrypt.name}]`;\n try {\n // initial common validation\n if (!args) { throw new Error('args required (E: fcd9b4aad85c4deba5fe5fde0b9ecb30)'); }\n if (!args.encryptedData) { throw new Error(`encryptedData required (E: f879f612428b4283bae089acee929a58)`); }\n\n // common defaults\n args.salt = args.salt || await getUUID(c.DEFAULT_GETUUID_SEEDSIZE);\n args.saltStrategy = args.saltStrategy || c.DEFAULT_SALT_STRATEGY;\n args.hashAlgorithm = args.hashAlgorithm || c.DEFAULT_HASH_ALGORITHM;\n args.recursionsPerHash = args.recursionsPerHash || c.DEFAULT_RECURSIONS_PER_HASH;\n\n // route to appropriate implementor\n let result: DecryptResult;\n if (args.blockMode || args.multipass) {\n result = await decryptImpl_blockMode(args);\n } else {\n result = await decryptImpl_stream(args);\n }\n\n // print out warnings/errors if necessary\n if ((result.warnings ?? []).length > 0) { result.warnings!.forEach(w => console.warn(`${lc} ${w}`)); }\n if ((result.errors ?? []).length > 0) { result.errors!.forEach(e => console.warn(`${lc} ${e}`)); }\n\n // we're done\n return result;\n // console.log(`${lc} encryptedDataDelimiter: ${encryptedDataDelimiter}`);\n } catch (error) {\n console.error(`${lc}${error.message}`);\n throw error;\n // const result = { ...args, errors: [error] };\n // delete (result as any).encryptedData;\n // delete (result as any).secret;\n // return result;\n }\n}\n", "import { SaltStrategy } from '@ibgib/encrypt-gib/dist/index.mjs';\n\nexport const DEFAULT_ENCRYPTION_INITIAL_RECURSIONS = 50000;\nexport const MIN_ENCRYPTION_INITIAL_RECURSIONS = 1000;\nexport const MAX_ENCRYPTION_INITIAL_RECURSIONS = 10000000;\nexport const MIN_ENCRYPTION_RECURSIONS_PER_HASH = 1;\nexport const MAX_ENCRYPTION_RECURSIONS_PER_HASH = 1000;\nexport const MIN_ENCRYPTION_SALT_LENGTH = 50;\nexport const MAX_ENCRYPTION_SALT_LENGTH = 99999;\nexport const MIN_ENCRYPTION_PASSWORD_LENGTH = 8;\nexport const MAX_ENCRYPTION_PASSWORD_LENGTH = 9999999;\nexport const DEFAULT_ENCRYPTION_SALT_STRATEGY: SaltStrategy = SaltStrategy.appendPerHash;\nexport const DEFAULT_ENCRYPTION_RECURSIONS_PER_HASH = 10;\nexport const DEFAULT_ENCRYPTION_HASH_ALGORITHM = 'SHA-256';\n\n/**\n * atom at the start of encryption ibgibs' `ib`.\n */\nexport const ENCRYPTION_ATOM = 'encryption';\n\n/**\n * default regexp for a simple name string.\n */\nexport const ENCRYPTION_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\n/**\n * An encryptions ibgib uses this rel8n name for its children encryptions.\n */\nexport const ENCRYPTION_REL8N_NAME = 'encryption';\n\n/**\n * atom for ciphertext...hmm\n */\nexport const CIPHERTEXT_ATOM = 'ciphertext';\n/**\n * Related encrypted ciphertext ibgibs will use this rel8n name.\n * Those ciphertext ibgibs will then relate to the encryption used.\n */\nexport const CIPHERTEXT_REL8N_NAME = 'ciphertext';\n", "import { IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibAddr, IbGib, IbGibRel8ns, TjpIbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\n\nimport {\n Witness,\n WitnessData_V1, WitnessResultData, WitnessResultIbGib, WitnessResultRel8ns,\n} from '../witness-types.mjs';\nimport { IbGibSpaceAny } from './space-base-v1.mjs';\nimport { ENCRYPTION_REL8N_NAME } from '../../common/encrypt/encrypt-constants.mjs';\nimport { WitnessCmdData, WitnessCmdIbGib, WitnessCmdRel8ns, } from '../witness-cmd/witness-cmd-types.mjs';\n\n/**\n * Marker type to show intent that it should be the spaceId, i.e.\n * space.data.uuid.\n */\nexport type SpaceId = string;\n\nexport type SpaceLocation = \"local\" | \"sync\";\nexport const SpaceLocation = {\n /**\n * space is a local space, with lower latency and direct usage with\n * metaspace. To be used as the primary local user space.\n *\n * no real proxy is involved, rather, we should be speaking \"directly\" with\n * the local location.\n */\n local: 'local' as SpaceLocation,\n /**\n * space is an outerspace, with higher latency, probably some kind of proxy\n * client access. More intended to be used with syncing...\n */\n outerspace: 'outerspace' as SpaceLocation,\n /**\n * in-memory-only space.\n *\n * Note: I haven't really incorporated this, but I have sketched an\n * in-memory innerspace and in the future, I think this will be heavily\n * utilized.\n */\n innerspace: 'innerspace' as SpaceLocation,\n}\nexport const VALID_SPACE_LOCATIONS = Object.values(SpaceLocation).concat();\n\nexport type SpaceType = \"user\" | \"sync\";\nexport const SpaceType = {\n /**\n * user space that usually (always?) acts locally as the main type of\n * storage for a user.\n *\n * This means that the user is actively working in this space, and it isn't\n * a derivative space. perhaps \"source\" would be better?\n */\n user: 'user' as SpaceType,\n /**\n * this is a derivative user space that is used to synchronize ibgib\n * timelines among two or more other spaces.\n */\n sync: 'sync' as SpaceType,\n}\n/**\n * Object.values(SpaceType).concat()\n *\n * for now, you can add valid space types here in initialization code to\n * manually extend this.\n */\nexport const VALID_SPACE_TYPES = Object.values(SpaceType).concat();\n\nexport type UserSpaceSubtype = 'node-filesystem';\n/**\n * specific/concrete subtype implementations\n */\nexport const UserSpaceSubtype = {\n /**\n * local user space is driven by a node filesystem concrete implementation.\n *\n * Note: This is actually implemented elsewhere, but I am deferring the\n * additional architectural requirements for putting the node filesystem and\n * extending this to include it. so I'm just putting this here. But in the\n * future, this should be moved to a node-specific library and brought in if\n * the app requires it.\n */\n node_filesystem: 'node-filesystem' as UserSpaceSubtype,\n}\nexport type SyncSpaceSubtype = 'aws-dynamodb';\nexport const SyncSpaceSubtype = {\n aws_dynamodb: 'aws-dynamodb' as SyncSpaceSubtype,\n}\n\nexport type SpaceSubtype = UserSpaceSubtype | SyncSpaceSubtype; // extend with logical OR types here\n/**\n * specific, concrete implementation of space\n */\nexport const SpaceSubtype = {\n ...UserSpaceSubtype,\n ...SyncSpaceSubtype,\n}\n/**\n * Object.values(SpaceSubtype).concat()\n *\n * for now, you can add valid subtypes here in initialization code to manually\n * extend this.\n */\nexport const VALID_SPACE_SUBTYPES = Object.values(SpaceSubtype).concat();\n\n/**\n * Common data among all ibgib spaces.\n */\nexport interface IbGibSpaceData extends WitnessData_V1 {\n /**\n * redeclaration for the name of the space, to make it required as opposed\n * to the base declaration which is optional.\n *\n * does NOT have to be unique.\n */\n name: string;\n /**\n * Redeclared over {@link WitnessData_V1.uuid} just for code readability,\n * showing the id to be a {@link SpaceId}, as well making it a required\n * field.\n */\n uuid: SpaceId;\n /**\n * if not given, defaults to \"user\" by convention.\n * @see {@link SpaceType}\n */\n type?: SpaceType;\n /**\n * should be required if {@link type} is set (truthy).\n * @see {@link SpaceSubtype}\n */\n subtype?: SpaceSubtype | undefined;\n /**\n * If true, when this space receives a command that includes incoming ibGibs\n * and ibGibAddrs, we will ensure the ibGibs have a 1-to-1 correspondence to\n * the addrs we're logging, and that the gib hashes are verified against the\n * ibGibs themselves.\n *\n * Otherwise, someone could pass in a bunch of legitimate addresses and\n * illegitimate ibGibs (that have little to do with the addresses). This\n * could at best be a coding mistake & at worst be malicious.\n */\n validateIbGibAddrsMatchIbGibs?: boolean;\n /**\n * interval between polling calls made to other spaces, e.g. sync spaces,\n * or used within a space to check inside itself for updates.\n *\n * ## notes\n *\n * * use as needed\n * * I want to just have this as a sync space setting, but since they are\n * enciphered, I don't want to just have them sitting around in plaintext.\n * * So I'm going to have it in the local app space, which the ibgibs\n * service will check in order for it to decide on interval.\n * * definitely a code smell, but I'm still resolving what a local app\n * space is vs the service that accesses it.\n */\n longPollingIntervalMs?: number;\n}\n\n/**\n * Specifically for ibgib spaces that are implemented via a path/subpath\n * strategy, i.e., using a filesystem-like addressing mechanism.\n */\nexport interface IbGibSpaceData_Subpathed extends IbGibSpaceData {\n /**\n * Redeclared here to make this required (not optional)\n */\n uuid: SpaceId;\n baseDir: string | any;\n encoding: string | any;\n /**\n * this is to help mitigate against too long path limits\n */\n mitigateLongPaths?: boolean;\n /**\n * if mitigating against long path lengths, this is the deciding split.\n *\n * so if the longPathLength is 250, and a full path would be 250, then\n * that is now a long path. 249 would be a short path and would not need\n * mitigation.\n */\n longPathLength?: number;\n baseSubPath: string;\n spaceSubPath: string;\n /**\n * if a filepath is too long, things get stuffed in here\n *\n * this is to help mitigate against too long path limits\n */\n longSubPath?: string;\n ibgibsSubPath: string;\n metaSubPath: string;\n binSubPath: string;\n dnaSubPath: string;\n n?: number;\n timestamp?: string;\n}\n\nexport interface IbGibSpaceRel8ns extends IbGibRel8ns_V1 {\n [ENCRYPTION_REL8N_NAME]?: IbGibAddr[];\n}\n\n\n/**\n * Cmds for interacting with ibgib spaces.\n *\n * Not all of these will be implemented for every space.\n *\n * ## todo\n *\n * change these commands to better structure, e.g., verb/do/mod, can/get/addrs\n * */\nexport type IbGibSpaceOptionsCmd =\n 'get' | 'put' | 'delete';\n/** Cmds for interacting with ibgib spaces. */\nexport const IbGibSpaceOptionsCmd = {\n /** Retrieve ibGib(s) out of the space (does not remove them). */\n get: 'get' as IbGibSpaceOptionsCmd,\n /** Registers/imports ibGib(s) into the space. */\n put: 'put' as IbGibSpaceOptionsCmd,\n /** Delete an ibGib from a space */\n delete: 'delete' as IbGibSpaceOptionsCmd,\n}\n\n/**\n * Flags to affect the command's interpretation.\n */\nexport type IbGibSpaceOptionsCmdModifier =\n 'can' | 'addrs' | 'latest' | 'watch' | 'unwatch' | 'tjps' | 'dependency-graph';\n/**\n * Flags to affect the command's interpretation.\n */\nexport const IbGibSpaceOptionsCmdModifier = {\n /**\n * Only interested if possibility to do command.\n *\n * This can be due to authorization or other.\n */\n can: 'can' as IbGibSpaceOptionsCmdModifier,\n /**\n * Only return the addresses of ibgibs\n */\n addrs: 'addrs' as IbGibSpaceOptionsCmdModifier,\n /**\n * Only interested in the latest one(s).\n *\n * The incoming addr(s) should be the tjp(s), since \"latest\"\n * only makes sense with unique timelines which are referenced by\n * their tjps.\n *\n * ## notes\n *\n * ATOW I'm actually using this in the aws dynamodb ibgib space to\n * get \"newer\" ibgibs, not just the latest.\n */\n latest: 'latest' as IbGibSpaceOptionsCmdModifier,\n /**\n * Ask to get updates on tjps in ibGibAddrs.\n */\n watch: 'watch' as IbGibSpaceOptionsCmdModifier,\n /*\n * Ask to stop getting updates on tjps in ibGibAddrs.\n */\n unwatch: 'unwatch' as IbGibSpaceOptionsCmdModifier,\n /**\n * Get the tjp ibgibs/addrs for given ibgib(s)\n */\n tjps: 'tjps' as IbGibSpaceOptionsCmdModifier,\n /**\n * Modifies the get command to retrieve a dependency graph.\n */\n dependencyGraph: 'dependency-graph' as IbGibSpaceOptionsCmdModifier,\n}\n\n/** Information for interacting with spaces. */\nexport interface IbGibSpaceOptionsData\n extends WitnessCmdData<IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier> {\n /**\n * If putting, this will force replacing the file.\n *\n * ## intent\n * atow this is just for `put` commands.\n */\n force?: boolean;\n /**\n */\n catchAllErrors?: boolean;\n /**\n */\n trace?: boolean;\n}\n\nexport interface IbGibSpaceOptionsRel8ns extends WitnessCmdRel8ns {\n}\n\nexport interface IbGibSpaceOptionsIbGib<\n TIbGib extends IbGib = IbGib_V1,\n TOptsData extends IbGibSpaceOptionsData = IbGibSpaceOptionsData,\n // TOptsRel8ns extends IbGibSpaceOptionsRel8ns = IbGibSpaceOptionsRel8ns\n TOptsRel8ns extends IbGibSpaceOptionsRel8ns = IbGibSpaceOptionsRel8ns,\n> extends WitnessCmdIbGib<TIbGib, IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier, TOptsData, TOptsRel8ns> {\n}\n\n/**\n * Shape of result data common to all (most) space interactions.\n *\n * This is in addition of course to {@link WitnessResultData}.\n */\nexport interface IbGibSpaceResultData extends WitnessResultData {\n /**\n * If the `cmd` is `canGet` or `canPut`, this holds the result that indicates\n * if you can or can't.\n */\n can?: boolean;\n /**\n * Addresses not found in a get.\n */\n addrsNotFound?: IbGibAddr[];\n /**\n * Addresses that are already in the space when requesting `put` or `canPut`.\n */\n addrsAlreadyHave?: IbGibAddr[];\n /**\n * Result map used when\n *\n * Mapping of incoming ibGibAddr -> latestAddr | null\n *\n * If there is a tjp/timeline -> maps to the latest in the store.\n * If there is no tjp -> maps to the incoming addr.\n * If the incoming addr is not found in the store -> maps to null.\n */\n latestAddrsMap?: { [addr: string]: IbGibAddr | null }\n /**\n * Map of TjpAddr -> newer LatestIbGibAddr notification.\n *\n * ## about\n *\n * When using the `watch` command modifier, a caller can subscribe to\n * updates/notifications to a timeline. When an update occurs in the space\n * via a `put` cmd that ends up creating/storing a newer ibgib address than\n * the one the receiving space knows the caller is aware of, it will try to\n * make the caller aware of the update.\n *\n * There are two ways to do this:\n * 1. Store the notification info locally until the next interaction between\n * the space and the caller.\n * 2. Send the notification actively to the caller.\n *\n * For the first implementation of notifications, only the first will be\n * implemented. Local notifications will be implemented, but active\n * internodal notification in the general sense will be implemented at a\n * later time.\n *\n * ## notes\n *\n * * may also implement a dedicated command to watch subscriptions.\n */\n watchTjpUpdateMap?: { [tjpAddr: string]: IbGibAddr; }\n}\n\nexport interface IbGibSpaceResultRel8ns extends WitnessResultRel8ns { }\n\nexport interface IbGibSpaceResultIbGib<\n TIbGib extends IbGib,\n TResultData extends IbGibSpaceResultData,\n TResultRel8ns extends IbGibSpaceResultRel8ns\n>\n extends WitnessResultIbGib<TIbGib, TResultData, TResultRel8ns> {\n}\n\n/**\n* Data space adapter/provider, such that a space should only have one type of...\n* * ibGib shape\n* * witness arg shape (which brings in external ibGibs)\n* * witness result shape\n*\n* So this interface facilitates that belief.\n*/\nexport interface IbGibSpace<\n TIbGib extends IbGib,\n TOptionsData extends IbGibSpaceOptionsData,\n TOptionsRel8ns extends IbGibSpaceOptionsRel8ns,\n TOptionsIbGib extends IbGibSpaceOptionsIbGib<TIbGib, TOptionsData, TOptionsRel8ns>,\n TResultData extends IbGibSpaceResultData,\n TResultRel8ns extends IbGibSpaceResultRel8ns,\n TResultIbGib extends IbGibSpaceResultIbGib<TIbGib, TResultData, TResultRel8ns>,\n TData extends IbGibSpaceData = IbGibSpaceData,\n TRel8ns extends IbGibSpaceRel8ns = IbGibRel8ns,\n>\n extends Witness<TOptionsIbGib, TResultIbGib, TData, TRel8ns> {\n witness(arg: TOptionsIbGib): Promise<TResultIbGib | undefined>;\n}\n\nexport type SpaceLockAction = 'lock' | 'unlock';\nexport type SpaceLockScope = 'all' | TjpIbGibAddr;\n\n/**\n * Data shape for {@link IbGibSpaceLockIbGib}.\n *\n * This includes the options passed in and contains any result data of the lock\n * as well.\n */\nexport interface IbGibSpaceLockData {\n /**\n * In-memory unique identifier associated with the lock.\n *\n * ## intent\n *\n * I intend this mainly as a device for differentiating among multiple\n * tabs open on the same browser. These share the same IndexedDB instance\n * (and thus the same space bucket), but they have different caching\n * mechanisms and interfaces to this bucket.\n */\n instanceId?: string;\n /**\n * self-explanatory\n */\n // action?: SpaceLockAction;\n /**\n * When setting the lock, this was the maximum amount of time the lock is\n * valid.\n *\n * {@link expirationUTC}\n */\n secondsValid?: number;\n /**\n * When setting the lock, this was the calculated expiration string based on\n * {@link secondsValid}.\n *\n * If the lock is not manually released, this will determine if the lock is\n * adhered to.\n */\n expirationUTC?: string;\n /**\n * The scope to which the lock applies.\n */\n scope: SpaceLockScope;\n /**\n * True if space was already locked.\n */\n alreadyLocked?: boolean;\n /**\n * True if caller's request to lock the space was executed.\n */\n success?: boolean;\n /**\n * If errored, this is the message.\n */\n errorMsg?: string;\n}\n\n/**\n * Options for the function that locks a space.\n\n * {@link IbGibSpaceLockData}\n * {@link IbGibSpaceLockIbGib}\n */\nexport interface IbGibSpaceLockOptions extends IbGibSpaceLockData {\n /**\n * the space to lock/unlock\n */\n space: IbGibSpaceAny;\n}\n\n/**\n * Rel8ns shape for {@link IbGibSpaceLockIbGib}\n *\n * marker interface atm\n */\nexport interface IbGibSpaceLockRel8ns extends IbGibRel8ns_V1 { }\n\n/**\n * When locking a space, this is the ibGib that contains informatino regarding\n * the process. This includes if the lock was successful, how long the lock is\n * good for, etc.\n *\n * ## notes\n *\n * * This is meant to be completely ephemeral and there will be no gib. There\n * may be many calls to lock/release in tight loops and atow it wouldn't seem\n * provide us with much benefit to store this kind of metadata.\n */\nexport interface IbGibSpaceLockIbGib\n extends IbGib_V1<IbGibSpaceLockData, IbGibSpaceLockRel8ns> {\n\n}\n\n/**\n * Marker type to indicate that a string is meant to be a transmission id.\n */\nexport type TxId = 'string';\n\n/**\n * we have a getDependencyGraph wrapper in the space base. This is the type of\n * that's result data.\n */\nexport interface GetDependencyGraphResultData extends IbGibSpaceResultData {\n count: number;\n}", "import { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { getRegExp, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { DynamicForm, FormItemInfo } from './form-items.mjs';\nimport { GLOBAL_LOG_A_LOT, SAFE_SPECIAL_CHARS } from '../../core-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Fluent-style builder helper class.\n *\n * I'm making this to share common fields' settings among witness classes.\n *\n * Descend from this class for sharing other commonalities.\n */\nexport class DynamicFormBuilder {\n protected lc: string = `[${DynamicFormBuilder.name}]`;\n\n protected items: FormItemInfo[] = [];\n protected what: string = '';\n /**\n * pool of uuids pre-calculated to be passed in to the builder. if this is\n * falsy, then it will use a Math.random() based approach.\n */\n protected idPool: string[] = [];\n\n /**\n * hacky wrapper for this.idPool.pop()\n */\n protected getNewId(): string {\n const lc = `${this.lc}[${this.getNewId.name}]`;\n if (this.idPool?.length > 0) {\n return this.idPool.pop() ?? '';\n } else {\n // weak implementation...\n let resultArray: string[] = [];\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n const charLength = chars.length;\n for (let i = 0; i < 32; i++) {\n let charIndex = Math.floor(Math.random() * charLength);\n resultArray.push(chars[charIndex]);\n }\n let id = resultArray.join('');\n if (logalot) { console.log(`${lc} id: ${id} (I: c6591ffee6d5bbea79ed19cfa6630422)`); }\n return id;\n }\n }\n\n /**\n * Start fluent calls with this.\n */\n forA({\n what,\n }: {\n /**\n * Common name for the reified concrete type of the witness.\n *\n * Used in things like placeholders, descriptions, etc.\n *\n * @example \"robbot\" or \"space\"\n */\n what: string,\n }): DynamicFormBuilder {\n this.what = what || 'thingy';\n return this;\n }\n\n protected addItem(item: FormItemInfo) {\n if (!item.uuid) { item.uuid = this.getNewId(); }\n this.items.push(item);\n }\n\n /**\n * Empty function simply for more natural looking fluent syntax.\n *\n * You can override this for custom form builders that descend from this\n * class.\n *\n * @returns this\n */\n with<T extends DynamicFormBuilder>({\n idPool,\n }: {\n /**\n * pre-built pool of uuids to draw from. this builder\n * will mutate this array.\n */\n idPool?: string[],\n }): T {\n if (idPool) { this.idPool = idPool; }\n return this as any as T;\n }\n\n /**\n * I'm not a great fluent builder writer for TypeScript,\n * and this function acts as a caster for which members of\n * which concrete classes to expose for the proceeding builder lines.\n *\n *\n * Basically, you use this to typecast the builder, possibly redundantly since\n * I don't have any ordering implemented atow.\n *\n * @returns typecasted fluent builder\n */\n and<T extends DynamicFormBuilder>(): T { return this as any as T; }\n\n name<T extends DynamicFormBuilder>({\n of: value,\n required = true,\n defaultValue,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n }): T {\n this.addItem({\n // witness.data.name\n name: \"name\",\n description: `What to call this ${this.what}. Doesn't have to be unique, no spaces, up to 32 alphanumerics/underscores in length.`,\n label: \"Name\",\n placeholder: `e.g. \"bob_the_cool\"`,\n regexp: getRegExp({ min: 1, max: 32, noSpaces: true }),\n regexpErrorMsg: '1 to 32 characters, no spaces, underscores allowed.',\n required,\n dataType: 'text',\n value,\n defaultValue,\n });\n return this as any as T;\n }\n\n description({\n of: value,\n required,\n defaultValue,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.description\n name: \"description\",\n description: `Description/notes for this ${this.what}.`,\n label: \"Description\",\n placeholder: `Describe these ${this.what} settings here...`,\n regexp: getRegExp({ min: 0, max: 155, chars: SAFE_SPECIAL_CHARS }),\n regexpErrorMsg: `0 to 155 alphanumerics or any of ${SAFE_SPECIAL_CHARS}`,\n // regexpSource: getRegExp({min: 0, max: 155, chars: SAFE_SPECIAL_CHARS}).source,\n dataType: 'textarea',\n required,\n value,\n defaultValue,\n });\n return this;\n }\n\n classname({\n of,\n required = true,\n }: {\n of: string,\n required?: boolean,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.classname\n name: \"classname\",\n description: `Technical setting that is the name of the ${this.what}'s class in computer code.`,\n label: \"Classname\",\n regexp: getRegExp({ min: 1, max: 128, noSpaces: true }),\n regexpErrorMsg: `1 to 128 alphanumerics or underscores without spaces`,\n // regexpSource: getRegExp({min: 1, max: 128, noSpaces: true}).source,\n dataType: 'text',\n value: of,\n readonly: true,\n required,\n });\n return this;\n }\n\n uuid({\n of,\n label,\n required,\n }: {\n of: string,\n label?: string,\n required?: boolean,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.uuid\n name: \"uuid\",\n description: `Unique(ish) id of the ${this.what}.`,\n label: label ?? \"ID\",\n dataType: 'text',\n value: of,\n regexp: UUID_REGEXP,\n regexpErrorMsg: '1 to 256 alphanumerics, underscores, dots, hyphens allowed.',\n readonly: true,\n required,\n });\n return this;\n }\n\n version({\n of,\n required,\n }: {\n of: string | undefined,\n required?: boolean,\n }): DynamicFormBuilder {\n this.addItem({\n // witness.data.version\n name: \"version\",\n description: `Technical setting indicating the version of the ${this.what}.`,\n label: \"Version\",\n dataType: 'text',\n value: of || '',\n readonly: true,\n required,\n });\n return this;\n }\n\n /**\n * To pass in a completely customized item info.\n *\n * @returns `this` for fluent builder\n */\n customItem(item: FormItemInfo): DynamicFormBuilder {\n this.addItem(item);\n return this;\n }\n\n\n outputItems(): FormItemInfo[] {\n return this.items;\n }\n\n outputForm({\n formName,\n label,\n }: {\n formName: string,\n label?: string,\n }): DynamicForm {\n return {\n name: formName,\n // description: this.description ?? `This is a form for a ${this.what}`,\n description: `This is a form for a ${this.what}`,\n label: label ?? this.what,\n items: this.items,\n } as DynamicForm;\n }\n}\n", "import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport { DynamicFormBuilder } from '../common/form/form-helper.mjs';\nimport { WitnessData_V1 } from '../witness/witness-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Fluent-style builder helper class.\n *\n * I'm making this to share common fields' settings among witness classes.\n *\n * Descend from this class for sharing other commonalities.\n */\nexport class WitnessFormBuilder extends DynamicFormBuilder {\n protected lc: string = `[${WitnessFormBuilder.name}]`;\n\n allowPrimitiveArgs({\n of,\n required = true,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.allowPrimitiveArgs\n name: \"allowPrimitiveArgs\",\n description: `Technical setting on if this ${this.what} accepts primitive incoming ibgibs`,\n label: \"Allow Primitive Args\",\n dataType: 'toggle',\n value: of ?? true,\n readonly: true,\n required,\n });\n return this;\n }\n\n catchAllErrors({\n of,\n required = true,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.catchAllErrors\n name: \"catchAllErrors\",\n description: `Technical setting on what the ${this.what} does when it encounters an internal error.`,\n label: \"Catch All Errors\",\n dataType: 'toggle',\n value: of ?? true,\n readonly: true,\n required,\n });\n return this;\n }\n\n persistOptsAndResultIbGibs({\n of,\n required = true,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.persistOptsAndResultIbGibs\n name: \"persistOptsAndResultIbGibs\",\n description: `Technical setting on if the ${this.what} maintains an audit trail of all of its inputs/outputs.`,\n label: \"Persist Opts and Result IbGibs\",\n dataType: 'toggle',\n value: of ?? false,\n readonly: true,\n required,\n });\n return this;\n }\n\n trace({\n of,\n required,\n }: {\n of: boolean | undefined,\n required?: boolean,\n }): WitnessFormBuilder {\n this.addItem({\n // witness.data.trace\n name: \"trace\",\n description: `Technical setting on if the ${this.what}'s activity should be traced (logged to the console).`,\n label: \"Trace\",\n dataType: 'toggle',\n value: of ?? false,\n readonly: true,\n required,\n });\n return this;\n }\n\n /**\n * Includes common witness fields.\n *\n * All common fields default to `true`, so set any you want to skip to\n * `false`.\n *\n * @returns `this` for fluent builder\n */\n commonWitnessFields({\n data,\n allowPrimitiveArgs = true,\n catchAllErrors = true,\n persistOptsAndResultIbGibs = true,\n trace = true,\n version = true,\n }: {\n data: WitnessData_V1,\n allowPrimitiveArgs?: boolean,\n catchAllErrors?: boolean,\n persistOptsAndResultIbGibs?: boolean,\n trace?: boolean,\n version?: boolean,\n }): WitnessFormBuilder {\n if (allowPrimitiveArgs) { this.allowPrimitiveArgs({ of: data.allowPrimitiveArgs }); }\n if (catchAllErrors) { this.catchAllErrors({ of: data.catchAllErrors }); }\n if (persistOptsAndResultIbGibs) { this.persistOptsAndResultIbGibs({ of: data.persistOptsAndResultIbGibs }); }\n if (trace) { this.trace({ of: data.trace }); }\n if (version) { this.version({ of: data.version }); }\n return this;\n }\n\n}\n", "import { getTimestampInTicks, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Gib, Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { AppData_V1, AppIbGib_V1, AppPromptResult, } from './app-types.mjs';\nimport { APP_NAME_REGEXP, APP_REL8N_NAME, } from './app-constants.mjs';\nimport { IbGibAppAny } from './app-base-v1.mjs';\nimport { IbGibSpaceAny } from '../space/space-base-v1.mjs';\nimport { WitnessFormBuilder } from '../witness-form-builder.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibTimelineUpdateInfo } from '../../common/other/other-types.mjs';\nimport { persistTransformResult, registerNewIbGib, rel8ToSpecialIbGib } from '../space/space-helper.mjs';\nimport { MetaspaceService } from '../space/metaspace/metaspace-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n\nexport function getAppResultMetadata({ app }: { app: IbGibAppAny }): string {\n return `${app.ib} ${getTimestampInTicks()}`;\n}\n\nexport function validateCommonAppData({\n appData,\n}: {\n appData: AppData_V1 | undefined,\n}): string[] {\n const lc = `[${validateCommonAppData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!appData) { throw new Error(`appData required (E: 3df782b29bc4406a87e4895cfcea28ed)`); }\n const errors: string[] = [];\n const {\n name, uuid, classname,\n } =\n appData;\n\n if (name) {\n if (!name.match(APP_NAME_REGEXP)) {\n errors.push(`name must match regexp: ${APP_NAME_REGEXP}`);\n }\n } else {\n errors.push(`name required.`);\n }\n\n if (uuid) {\n if (!uuid.match(UUID_REGEXP)) {\n errors.push(`uuid must match regexp: ${UUID_REGEXP}`);\n }\n } else {\n errors.push(`uuid required.`);\n }\n\n if (classname) {\n if (!classname.match(APP_NAME_REGEXP)) {\n errors.push(`classname must match regexp: ${APP_NAME_REGEXP}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getAppIb({\n appData,\n classname,\n}: {\n appData: AppData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getAppIb.name}]`;\n try {\n const validationErrors = validateCommonAppData({ appData });\n if (validationErrors.length > 0) { throw new Error(`invalid appData: ${validationErrors} (E: 9aff04f0cfc54a5188ca8bc40764160d)`); }\n if (classname) {\n if (appData.classname && appData.classname !== classname) { throw new Error(`classname does not match appData.classname (E: 66f1447eef97485fba521c40980f5eb5)`); }\n } else {\n classname = appData.classname;\n if (!classname) { throw new Error(`classname required (E: 5f6ffb4317044125b94f662070e1f40b)`); }\n }\n\n const { name, uuid } = appData;\n return `app ${classname} ${name} ${uuid}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `app ${classname} ${name} ${uuid}`\n *\n * NOTE this is space-delimited\n */\nexport function getInfoFromAppIb({\n appIb,\n}: {\n appIb: Ib,\n}): {\n appClassname: string,\n appName: string,\n appId: string,\n} {\n const lc = `[${getInfoFromAppIb.name}]`;\n try {\n if (!appIb) { throw new Error(`appIb required (E: 6b065aee67e641ba9f9c6db367ebb0fb)`); }\n\n const pieces = appIb.split(' ');\n\n return {\n appClassname: pieces[1],\n appName: pieces[2],\n appId: pieces[3],\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function getAppInfoIb({\n appData,\n appTjpGib,\n classname,\n}: {\n appData: AppData_V1,\n appTjpGib: Gib,\n /**\n * Not sure why i have this here, since it should always be in the appData.classname...\n */\n classname?: string,\n}): Ib {\n const lc = `[${getAppIb.name}]`;\n try {\n const validationErrors = validateCommonAppData({ appData });\n if (validationErrors.length > 0) { throw new Error(`invalid appData: ${validationErrors} (E: 7be1f54ce8af4e4982966b2dedb4cf6e)`); }\n if (classname) {\n if (appData.classname && appData.classname !== classname) { throw new Error(`classname does not match appData.classname (E: 64bd9eaef1f94be8856e18b791d4ae52)`); }\n } else {\n classname = appData.classname;\n if (!classname) { throw new Error(`classname required (E: 8d194cf8fb3f4c8eb2f708e0ccfe187c)`); }\n }\n\n const { name, uuid } = appData;\n return `info_app ${classname} ${name} ${uuid} ${appTjpGib ?? 0}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `info_app ${classname} ${name} ${uuid} ${appTjpGib ?? 0}`\n *\n * NOTE this is space-delimited\n */\nexport function getInfoFromAppInfoIb({\n appInfoIb,\n}: {\n appInfoIb: Ib,\n}): {\n appClassname: string;\n appName: string;\n appId: string;\n appTjpGib: Gib;\n} {\n const lc = `[${getInfoFromAppIb.name}]`;\n try {\n if (!appInfoIb) { throw new Error(`appInfoIb required (E: d12756f218144d22acb14c794dd3eeef)`); }\n\n const pieces = appInfoIb.split(' ');\n\n if (pieces.length !== 5) { throw new Error(`invalid appInfoIb. Expected space-delimited pieces.length === 5 (E: 21bfc58e4d88c298680ea95bc6dfc622)`); }\n\n return {\n appClassname: pieces[1],\n appName: pieces[2],\n appId: pieces[3],\n appTjpGib: pieces[4],\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n\n/**\n * Prompts the user a form to build the app.\n *\n * Once prompted, the app is:\n * 1. validated\n * 2. persisted in the given {@link space}\n * 3. registered with the space\n * 4. related to the space's special apps index\n * 5. new app is returned\n *\n * @returns newly created app ibgib (witness)\n */\nexport async function createNewApp({\n fnPromptApp,\n ibgibs,\n space,\n}: {\n /**\n * factory function for creating/editing an app ibgib.\n *\n * @param space space within which we're working\n * @param ibGib set if editing app, null if creating\n * @returns TransformResult<IbGibAppAny> for app ibgib created/edited\n */\n fnPromptApp: (space: IbGibSpaceAny, ibGib: AppIbGib_V1 | null) => Promise<AppPromptResult | undefined>,\n /**\n * Either {@link common} or {@link ibgibs} is required\n * @hack\n */\n ibgibs?: MetaspaceService,\n /**\n * space within which to create the app. if not provided, the\n * defaults to the local user space via {@link common} or {@link ibgibs}.\n */\n space: IbGibSpaceAny,\n}): Promise<IbGibAppAny | undefined> {\n const lc = `[${createNewApp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!ibgibs) { throw new Error(`ibgibs all powerful service required. (E: b24e78de0d204dc78909022bee296b30)`); }\n\n space = space ?? await ibgibs.getLocalUserSpace({ lock: true });\n\n // prompt user to create the ibgib, passing in null because we're\n // creating not editing.\n let resApp = await fnPromptApp(space, /*ibGib*/ null);\n\n if (!resApp) { throw new Error(`resApp falsy after prompt for app. (E: 2225a567abcd680a5e957e81fbb64123)`); }\n\n /** this should be the witness class itself at this point. */\n const newApp = (resApp.newIbGib as IbGibAppAny);\n\n let allIbGibs: IbGib_V1[] = [];\n allIbGibs.push(newApp);\n resApp.intermediateIbGibs?.forEach((x: IbGib_V1) => allIbGibs.push(x));\n resApp.dnas?.forEach((x: IbGib_V1) => allIbGibs.push(x));\n for (let i = 0; i < allIbGibs.length; i++) {\n const ibGib = allIbGibs[i];\n const validationErrors = await validateIbGibIntrinsically({ ibGib });\n if ((validationErrors ?? []).length > 0) { throw new Error(`(UNEXPECTED) invalid app ibgib created. validationErrors: ${validationErrors}. app: ${pretty(newApp.toIbGibDto())} (E: 54cfc2f6bc284ed79be91d2da5e4bd2f)`); }\n }\n\n await persistTransformResult({ resTransform: resApp, space });\n const { zeroSpace, fnBroadcast, fnUpdateBootstrap } = ibgibs;\n await registerNewIbGib({\n ibGib: newApp,\n space,\n fnBroadcast: (x: IbGibTimelineUpdateInfo) => fnBroadcast(x),\n });\n\n await rel8ToSpecialIbGib({\n type: \"apps\",\n rel8nName: APP_REL8N_NAME,\n ibGibsToRel8: [newApp],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n return newApp;\n } catch (error) {\n debugger; // before error\n console.error(`${lc} ${error.message}`);\n return;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport class AppFormBuilder extends WitnessFormBuilder {\n protected lc: string = `[${AppFormBuilder.name}]`;\n\n constructor() {\n super();\n this.what = 'app';\n }\n\n icon({\n of,\n required,\n defaultValue,\n iconsList,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n iconsList: string[],\n }): AppFormBuilder {\n // const exampleIonicons = IONICONS.slice(0, 4).map(x => `\"${x}\"`).join(', ');\n const exampleIonicons = iconsList.slice(0, 4).map(x => `\"${x}\"`).join(', ');\n this.addItem({\n // witness.data.outputPrefix\n name: \"icon\",\n description: `Icon name for the app's icon in the app bar. (NOTE: Only ionicons right now, e.g. ${exampleIonicons}). See https://ionic.io/ionicons for a full list.`,\n label: \"Icon\",\n fnValid: (x: string | number) => { return typeof x === 'string' && iconsList.includes(x); },\n defaultErrorMsg: `Must be a valid icon from the icons list.`,\n dataType: 'select',\n value: of,\n defaultValue: defaultValue || 'beer',\n selectOptions: [\n ...iconsList,\n ],\n required,\n });\n return this;\n }\n\n}\n\n// export function documentLocationIsAtWelcomePage(): boolean {\n// return ['welcome', '/welcome', '/welcome/'].includes(document.location.pathname);\n// }\n", "import { AppData_V1, AppRel8ns_V1 } from '../app-types.mjs';\n\nexport const DEFAULT_UUID_CHAT_APP = '0';\nexport const DEFAULT_NAME_CHAT_APP = 'chat_gib';\nexport const DEFAULT_DESCRIPTION_CHAT_APP =\n `A chat app done ibgib style, enabling infinitely nesting comments, pics and links. It's ibgibs all the way down...`;\n\n\nexport interface ChatAppData_V1 extends AppData_V1 {\n\n}\n\n\nexport interface ChatAppRel8ns_V1 extends AppRel8ns_V1 {\n\n}\n\n/**\n * Default data values for a random app.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_CHAT_APP_DATA_V1: ChatAppData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_CHAT_APP,\n name: DEFAULT_NAME_CHAT_APP,\n description: DEFAULT_DESCRIPTION_CHAT_APP,\n // classname: ChatApp_V1.name,\n classname: `ChatApp_V1`,\n\n icon: 'chatbubbles',\n\n persistOptsAndResultIbGibs: false,\n allowPrimitiveArgs: true,\n catchAllErrors: true,\n trace: false,\n}\nexport const DEFAULT_CHAT_APP_REL8NS_V1: ChatAppRel8ns_V1 | undefined = undefined;\n", "import { AppData_V1, AppRel8ns_V1 } from '../app-types.mjs';\n\nexport const DEFAULT_UUID_RAW_APP = '0';\nexport const DEFAULT_NAME_RAW_APP = 'raw_gib';\nexport const DEFAULT_DESCRIPTION_RAW_APP =\n `Explorer app for navigating raw ibgib data.`;\n\n\nexport interface RawAppData_V1 extends AppData_V1 {\n\n}\n\nexport interface RawAppRel8ns_V1 extends AppRel8ns_V1 {\n\n}\n\n/**\n * Default data values for a random app.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_RAW_APP_DATA_V1: RawAppData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_RAW_APP,\n name: DEFAULT_NAME_RAW_APP,\n description: DEFAULT_DESCRIPTION_RAW_APP,\n // classname: RawApp_V1.name,\n classname: `RawApp_V1`,\n\n icon: 'paper-plane',\n\n persistOptsAndResultIbGibs: false,\n allowPrimitiveArgs: true,\n catchAllErrors: true,\n trace: false,\n}\n\nexport const DEFAULT_RAW_APP_REL8NS_V1: RawAppRel8ns_V1 | undefined = undefined;\n", "import { Gib } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { AppData_V1, AppRel8ns_V1 } from '../app-types.mjs';\n\nexport const DEFAULT_UUID_TODO_APP = '0';\nexport const DEFAULT_NAME_TODO_APP = 'todo_gib';\nexport const DEFAULT_DESCRIPTION_TODO_APP =\n `Todo app for viewing and interacting with ibgibs like they're checklists.`;\n\n\nexport interface TodoAppData_V1 extends AppData_V1 {\n\n}\n\nexport interface TodoAppRel8ns_V1 extends AppRel8ns_V1 {\n\n}\n\n/**\n * Default data values for a random app.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_TODO_APP_DATA_V1: TodoAppData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_TODO_APP,\n name: DEFAULT_NAME_TODO_APP,\n description: DEFAULT_DESCRIPTION_TODO_APP,\n // classname: TodoApp_V1.name,\n classname: `TodoApp_V1`,\n\n icon: 'checkbox',\n\n persistOptsAndResultIbGibs: false,\n allowPrimitiveArgs: true,\n catchAllErrors: true,\n trace: false,\n}\nexport const DEFAULT_TODO_APP_REL8NS_V1: TodoAppRel8ns_V1 | undefined = undefined;\n\n/**\n * when an ibgib has children that are checked/unchecked using\n * the (a?) todo app, this is the rel8n name to the info.\n */\nexport const TODO_INFO_REL8N_NAME = 'todo';\nexport const TODO_INFO_IB = 'todo_info';\n\n\nexport interface TodoInfoData_V1 extends IbGibData_V1 {\n tjpGibsDone: Gib[];\n}\n\nexport interface TodoInfoRel8ns_V1 extends IbGibRel8ns_V1 {\n}\n\nexport interface TodoInfoIbGib_V1 extends IbGib_V1<TodoInfoData_V1, TodoInfoRel8ns_V1> { }\n", "import { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/index.mjs\";\nimport { getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { validateIbGibIntrinsically } from \"@ibgib/ts-gib/dist/V1/validate-helper.mjs\";\n\nimport { BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY, BOOTSTRAP_IBGIB_ADDR } from \"./bootstrap-constants.mjs\";\nimport { BootstrapData, BootstrapRel8ns } from \"./bootstrap-types.mjs\";\n\nexport async function validateBootstrapIbGib(bootstrapSpace: IbGib_V1): Promise<boolean> {\n const lc = `[${validateBootstrapIbGib.name}]`;\n const errors: string[] = [];\n try {\n const addr = getIbGibAddr({ ibGib: bootstrapSpace });\n if (addr !== BOOTSTRAP_IBGIB_ADDR) {\n errors.push(`invalid bootstrapSpace addr. Should equal \"${BOOTSTRAP_IBGIB_ADDR}\" (E: ecfdbed719284db7a1aa3f867f706fe9)`);\n }\n let intrinsicErrors = await validateIbGibIntrinsically({ ibGib: bootstrapSpace });\n if (intrinsicErrors?.length ?? -1 > 0) { intrinsicErrors!.forEach(e => errors.push(e)); }\n\n const data = (bootstrapSpace.data as BootstrapData);\n const rel8ns = (bootstrapSpace.rel8ns as BootstrapRel8ns);\n\n if (Object.keys(data || {}).length === 0) {\n errors.push(`invalid bootstrapSpace data. data required (E: 5a9bd15dd0644f9b93cafbbba660cfdf)`);\n }\n if ((data.spaceIds ?? []).length === 0) {\n errors.push(`invalid bootstrapSpace, data.spaceIds required. (E: 6b91ddc12cfd41e59ded7d7502c1909f)`);\n }\n if (Object.keys(bootstrapSpace.rel8ns || {}).length === 0) {\n errors.push(`invalid bootstrapSpace rel8ns (empty). Should have at least one rel8n, with rel8nName corresponding to the spaceId (E: b188ce4ae25e49f794f35e141bc2ecde)`);\n }\n data.spaceIds.forEach((spaceId: string) => {\n if ((rel8ns[spaceId] ?? []).length === 0) {\n errors.push(`invalid bootstrap. Each spaceId listed in data should have a corresponding address in rel8ns. spaceId (${spaceId}) missing. (E: 62dd0d76e29a415a98b4b27deb8db17e)`);\n }\n });\n if (!data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]) {\n errors.push(`invalid bootstrap. data.${BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY} required. (E: f763af2e275f445cbf1db5801bacafad)`);\n } else if ((rel8ns[data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]] ?? []).length === 0) {\n errors.push(`invalid bootstrap. data.${BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY} (${data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]}) not found in rel8ns. (E: 44d0799d232f4a51a0b0019ebebe019f)`);\n }\n if (errors.length === 0) {\n return true;\n } else {\n console.error(`${lc} errors: ${errors.join('|')}`);\n return false;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false;\n }\n}\n", "/**\n * @module meta-stone constants\n *\n * constants are in this file!\n */\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// export const SOME_TYPE_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * atom used in ibs\n *\n * atow (11/2023) this should also be (as with most atoms) the ib of the parent\n * primitive ibgib used when creating a new ibgib (forking a primitive ibgib\n * with this ib).\n */\nexport const META_STONE_ATOM = 'meta_stone';\n\n/**\n * default regexp for a simple name string.\n */\nexport const META_STONE_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\n/**\n * for use when creating a metastone targeting an ibgib without a tjp (i.e. a\n * stone ibgib itself).\n */\nexport const DEFAULT_META_STONE_TJPGIB = 'undefined';\n/**\n * for use when targetIbGib.data.n is falsy or NaN\n */\nexport const DEFAULT_META_STONE_N = -1;\n/**\n * for use when targetIbGib.data.timestamp is falsy\n */\nexport const DEFAULT_META_STONE_TIMESTAMP = 'undefined';\n\n/**\n * rel8n name pointing from the metastone to its target ibgib.\n */\nexport const META_STONE_TARGET_REL8N_NAME = 'target';\n/**\n * rel8n name pointing from the metastone to the target's temporal junction\n * point.\n */\nexport const META_STONE_TARGET_TJP_REL8N_NAME = 'targetTjp';\n", "/**\n * @module meta-stone helper/util/etc. functions\n *\n * this is where you will find helper functions like those that generate\n * and parse ibs for meta-stone.\n */\n\n// import * as pathUtils from 'path';\n// import { statSync } from 'node:fs';\n// import { readFile, } from 'node:fs/promises';\n// import * as readline from 'node:readline/promises';\n// import { stdin, stdout } from 'node:process'; // decide if use this or not\n\nimport {\n extractErrorMsg, getTimestamp, getTimestampInTicks,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { Ib, IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport {\n validateGib, validateIbGibAddr, validateIbGibIntrinsically,\n validateRel8nsIntrinsically\n} from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { getIbAndGib, getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { GIB } from '@ibgib/ts-gib/dist/V1/constants.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport {\n MetaStoneData_V1, MetaStoneRel8ns_V1, MetaStoneIbGib_V1, MetaStoneIbInfo,\n} from './meta-stone-types.mjs';\nimport {\n DEFAULT_META_STONE_N, DEFAULT_META_STONE_TIMESTAMP,\n DEFAULT_META_STONE_TJPGIB, META_STONE_ATOM, META_STONE_TARGET_REL8N_NAME,\n META_STONE_TARGET_TJP_REL8N_NAME,\n} from './meta-stone-constants.mjs';\nimport { constantIbGib, getTimestampInfo, getTjpAddr, isBinary } from '../other/ibgib-helper.mjs';\n\n/**\n * for verbose logging\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport function validateCommonMetaStoneIb({\n ib,\n}: {\n ib: Ib,\n}): string[] {\n const lc = `[${validateCommonMetaStoneIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const errors: string[] = [];\n\n const pieces = ib.split(' ');\n\n // atom\n const atom = pieces[0];\n if (atom !== META_STONE_ATOM) {\n errors.push(`${lc} invalid ib. atom is expected to be META_STONE_ATOM: ${META_STONE_ATOM} (E: a9812bffc18f44418aa091fb0ed260bd)`)\n }\n\n // validate tjpGib\n const tjpGib = pieces[1];\n const tjpGibValidationErrors = validateGib({ gib: tjpGib }) ?? [];\n if (tjpGibValidationErrors.length > 0) {\n errors.push(`invalid ib. pieces[1] should be a valid tjpGib. validation errors: ${tjpGibValidationErrors} (E: 233db2babfbe4d28a80f98261f1c0e01)`);\n }\n\n // n\n const nAsString = pieces[2];\n const parsedN = Number.parseInt(nAsString);\n if (isNaN(parsedN)) { errors.push(`invalid ib. space-delimited pieces[2] should be valid integer (E: 71df0d6abd7b4cf4b11621e6bfb556cd)`); }\n\n // timestampInTicks\n const timestampInTicks = pieces[3];\n if (timestampInTicks === 'undefined') {\n // this happens when it's a binary ibgib or just doesn't have a timestamp in the data map\n } else {\n const timestampInfo = getTimestampInfo({ timestamp: timestampInTicks });\n if (!timestampInfo.valid) {\n errors.push(`invalid ib. pieces[3] should be valid timestampInTicks. emsg: (${timestampInfo.emsg}) (E: 06dae01d66f54f54b71d9c920c730840)`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function validateCommonMetaStoneData({\n data,\n}: {\n data?: MetaStoneData_V1,\n}): string[] {\n const lc = `[${validateCommonMetaStoneData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!data) { throw new Error(`data required (E: c50ac422af4501b72af12481fbd4961e)`); }\n const errors: string[] = [];\n\n // we need to be careful here. we have two different \"data\" objects: 1)\n // the metastone's data, and 2) the metastone's targetData.\n\n // first validate 1) the metastone's data itself (barring the\n // targetData)\n const { targetData, timestamp } = data;\n\n // timestamp is required\n const timestampInfo = getTimestampInfo({ timestamp });\n if (!timestampInfo.valid) {\n errors.push(`invalid timestampInTicks. should be valid ticks number. (E: 7e381ed5b0c8486b90cfd37676da3626)`);\n }\n\n const {\n tjpGib: targetTjpGib,\n n: targetN,\n timestamp: targetTimestamp,\n } =\n targetData;\n\n // target tjpGib\n if (targetTjpGib) {\n if (targetTjpGib === 'undefined') {\n // target had no tjpgib\n } else {\n const tjpGibValidationErrors = validateGib({ gib: targetTjpGib }) ?? [];\n if (tjpGibValidationErrors.length > 0) {\n errors.push(`invalid data (targetTjpGib). validation errors: ${tjpGibValidationErrors} (E: d216b12eb75544ef8c5ffb27cd132e2e)`);\n }\n }\n }\n\n // target n\n if (typeof targetN !== 'number') {\n errors.push(`invalid n. should be valid integer. if target.data.n is falsy, targetN should be -1 (E: 8f234967b388ad80776c8054d71fbc23)`);\n }\n\n // target timestamp (optional)\n if (targetTimestamp) {\n if (targetTimestamp === 'undefined') {\n // target had no timestamp\n } else {\n const targetTimestampInfo = getTimestampInfo({ timestamp: targetTimestamp });\n if (!targetTimestampInfo.valid) {\n errors.push(`invalid targetTimestamp. emsg: ${targetTimestampInfo.emsg} (E: c15d4fd2a2b74a0fab3223e83d954379)`);\n }\n }\n\n }\n const timestampDate = new Date(timestamp);\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function validateCommonMetaStoneRel8ns({\n rel8ns,\n}: {\n rel8ns?: MetaStoneRel8ns_V1,\n}): string[] {\n const lc = `[${validateCommonMetaStoneRel8ns.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!rel8ns) { throw new Error(`rel8ns required (E: 7737ae550e2347e68c67b715c1221393)`); }\n const errors: string[] = [];\n\n // basic rel8ns validation\n const intrinsicErrors = validateRel8nsIntrinsically({ rel8ns: rel8ns ?? {} }) ?? [];\n if (intrinsicErrors.length > 0) {\n errors.push(`invalid rel8ns intrinsically. errors: ${intrinsicErrors.join('|')}. (E: abc91753f0f946afa0a3ea2c1917960f)`);\n }\n\n // [META_STONE_TARGET_REL8N_NAME]: IbGibAddr[];\n // all metastones should have exactly 1 targetAddr\n const targetAddrs = rel8ns[META_STONE_TARGET_REL8N_NAME] ?? [];\n if (targetAddrs.length === 0) {\n errors.push(`invalid metastone rel8ns. should have exactly 1 rel8nName ${META_STONE_TARGET_REL8N_NAME}. has 0. (E: 8181652da9e89613e204d245db12d723)`);\n } else if (targetAddrs.length > 1) {\n errors.push(`invalid metastone rel8ns. should have exactly 1 rel8nName ${META_STONE_TARGET_REL8N_NAME}. has ${targetAddrs.length}. (E: 2318047c6fea482d9f53febe02cf8912)`);\n }\n\n // [META_STONE_TARGET_TJP_REL8N_NAME]?: IbGibAddr[];\n // optional rel8n, should have 0 or 1\n // if we want to get picky, we could check to make sure it is a tjpAddr\n let targetTjpAddrs = rel8ns[META_STONE_TARGET_TJP_REL8N_NAME] ?? [];\n if (targetTjpAddrs.length > 1) {\n errors.push(`invalid metastone rel8ns. should have 0 or 1 rel8nName ${META_STONE_TARGET_TJP_REL8N_NAME}. has ${targetTjpAddrs.length}. (E: 34a8ae53825f46caa7ad024a64400db2)`)\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * performs validation on the ib, data and rel8ns, as well as validates the\n * ibgib intrinsically (i.e. ensures the gib hash is correct)\n * @returns errors array if any found, otherwise undefined (if no errors)\n */\nexport async function validateCommonMetaStoneIbGib({\n ibGib,\n}: {\n ibGib: MetaStoneIbGib_V1,\n}): Promise<string[] | undefined> {\n const lc = `[${validateCommonMetaStoneIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f32249d08105b997871a06cdee006311)`); }\n const intrinsicErrors: string[] = await validateIbGibIntrinsically({ ibGib: ibGib }) ?? [];\n\n if (!ibGib.data) { throw new Error(`MetaStoneIbGib.data required (E: 96432cf4f919d339277d9a1c61ea4264)`); }\n\n // validate ib happens in parse...if only i had a memory...\n const ibErrors: string[] = [];\n try {\n const { atom, tjpGib, n, timestampInTicks } =\n parseMetaStoneIb({ ib: ibGib.ib });\n } catch (error) {\n ibErrors.push(extractErrorMsg(error));\n }\n\n const dataErrors = validateCommonMetaStoneData({ data: ibGib.data });\n const rel8nsErrors = validateCommonMetaStoneRel8ns({ rel8ns: ibGib.rel8ns });\n\n const result = [\n ...(intrinsicErrors ?? []),\n ...(ibErrors ?? []),\n ...(dataErrors ?? []),\n ...(rel8nsErrors ?? []),\n ];\n if (result.length > 0) {\n return result;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * validates the given `data` and builds the ib based on that data.\n *\n * _NOTE: This is **NOT** the function to use to build a metastone based a target ibgib._\n *\n * @returns ib shaped for metastone (atow 11/2023 has tjpGib,n,timestampInTicks)\n */\nexport function getMetaStoneIb({\n data,\n classname,\n}: {\n data: MetaStoneData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getMetaStoneIb.name}]`;\n try {\n const validationErrors = validateCommonMetaStoneData({ data });\n if (validationErrors.length > 0) { throw new Error(`invalid MetaStone data: ${validationErrors} (E: ac642cc5915f0fc0508cb2fb728c86fa)`); }\n if (classname) {\n if (logalot) { console.log(`${lc} classname not required. no big deal that it is provided here. (I: db4d41471cb976795afd3fa89f8cb823)`); }\n }\n\n // we need to be careful here. we have two different \"data\" objects: 1)\n // the metastone's data, and 2) the metastone's targetData.\n\n // these are validated in common data\n const targetTimestamp = data.targetData.timestamp;\n const targetTimestampInTicks = !!targetTimestamp && targetTimestamp !== 'undefined' ?\n getTimestampInTicks(targetTimestamp) :\n DEFAULT_META_STONE_TIMESTAMP;\n\n return `${META_STONE_ATOM} ${data.targetData.tjpGib} ${data.targetData.n} ${targetTimestampInTicks}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `${META_STONE_ATOM} ${data.targetData.tjpGib} ${data.targetData.n} ${targetTimestampInTicks}`;\n *\n * NOTE this ib is space-delimited\n */\nexport function parseMetaStoneIb({\n ib,\n}: {\n ib: Ib,\n}): MetaStoneIbInfo {\n const lc = `[${parseMetaStoneIb.name}]`;\n try {\n if (!ib) { throw new Error(`MetaStone ib required (E: 8e74e098d7aeef52d3952e35150d83ed)`); }\n\n const validationErrors = validateCommonMetaStoneIb({ ib });\n if (validationErrors.length > 0) { throw new Error(`invalid ib. validationErrors: ${validationErrors} (E: a6107f62200eb943e523f70f51300623)`); }\n\n const pieces = ib.split(' ');\n\n return {\n atom: pieces[0],\n tjpGib: pieces[1],\n n: Number.parseInt(pieces[2]),\n timestampInTicks: pieces[3],\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * metastone ibgibs are for things like helping to keep track of the latest\n * ibgib in a timeline (similar to the HEAD pointer in e.g. git).\n *\n * @returns true if `addr` is for a metastone ibgib, else false\n */\nexport function isMetaStone({\n addr,\n ibGib,\n}: {\n addr?: IbGibAddr,\n ibGib?: IbGib_V1,\n}): boolean {\n // ignore edge case of checking if both are provided that they both should\n // be equal.\n\n addr ||= getIbGibAddr({ ibGib });\n if (!addr) { throw new Error(`either addr or ibGib required. (E: 372b2574d5a9fac298119beed9f6e223)`); }\n return addr.startsWith(`${META_STONE_ATOM} `);\n}\n\n/**\n * factory function that generates a metastone (constant) ibgib based on the\n * given `ibGib`.\n */\nexport async function newUpMetaStone({\n targetIbGib,\n}: {\n targetIbGib: IbGib_V1,\n}): Promise<MetaStoneIbGib_V1> {\n const lc = `[${newUpMetaStone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d846313065c89c89e4b5afa2df2b7123)`); }\n\n const targetAddr = getIbGibAddr({ ibGib: targetIbGib });\n const targetTjpAddr = getTjpAddr({ ibGib: targetIbGib, defaultIfNone: \"incomingAddr\" })!;\n\n let metaStoneData: MetaStoneData_V1;\n const metaStoneRel8ns: MetaStoneRel8ns_V1 = {\n [META_STONE_TARGET_REL8N_NAME]: [targetAddr],\n [META_STONE_TARGET_TJP_REL8N_NAME]: [targetTjpAddr],\n };\n\n // const targetGibInfo = getGibInfo({ ibGibAddr: targetAddr });\n if (!targetIbGib.gib) { throw new Error(`(UNEXPECTED) targetIbGib.gib falsy? (E: 28eaa8a799021dadd87b043711aee826)`); }\n /**\n * * if the targetIbGib is the tjp, then its gib is the tjpGib.\n * * if the targetIbGib has a tjp, then gibInfo.tjpGib is what we want.\n * * if the targetIbGib is a stone, then we pretend that it is the\n * tjpGib (any stone might one day be raised up & come to life)\n */\n const targetTjpGib = targetIbGib.data?.isTjp ?\n targetIbGib.gib :\n getGibInfo({ ibGibAddr: targetAddr }).tjpGib ?? targetIbGib.gib;\n\n if (targetTjpGib === GIB) { throw new Error(`cannot create metastone for primitive ibgib (E: 2887e8ef83381a0698256b7bc7531826)`); }\n\n const metaStoneTimestampDate = new Date();\n /**\n * timestamp for the metastone itself (not the target.data.timestamp)\n */\n const metaStoneTimestamp = getTimestamp(metaStoneTimestampDate);\n const metaStoneTimestampMs = metaStoneTimestampDate.getMilliseconds();\n\n if (targetIbGib.data) {\n if (isBinary({ ibGib: targetIbGib })) {\n // binary data is just a uint8array\n metaStoneData = {\n targetData: {\n n: -1,\n tjpGib: targetTjpGib,\n },\n timestamp: metaStoneTimestamp,\n timestampMs: metaStoneTimestampMs,\n };\n } else {\n metaStoneData = {\n targetData: {\n n: targetIbGib.data.n ?? DEFAULT_META_STONE_N,\n tjpGib: targetTjpGib,\n timestamp: targetIbGib.data.timestamp ?? DEFAULT_META_STONE_TIMESTAMP,\n },\n timestamp: metaStoneTimestamp,\n timestampMs: metaStoneTimestampMs,\n }\n if (targetIbGib.data?.isTjp) { metaStoneData.targetData.isTjp = true; }\n }\n } else {\n // no target data\n metaStoneData = {\n targetData: {\n n: DEFAULT_META_STONE_N,\n tjpGib: targetTjpGib,\n },\n timestamp: metaStoneTimestamp,\n timestampMs: metaStoneTimestampMs,\n }\n }\n\n // now that we have the data, we can build the ib\n const metaStoneIb = getMetaStoneIb({ data: metaStoneData });\n\n // now that we have the data, rel8ns, and the ib, we can create the\n // stone (which is a constant ibgib).\n const metaStoneIbGib = await constantIbGib<MetaStoneData_V1, MetaStoneRel8ns_V1>({\n parentPrimitiveIb: META_STONE_ATOM,\n ib: metaStoneIb,\n data: metaStoneData,\n rel8ns: metaStoneRel8ns,\n }) as MetaStoneIbGib_V1;\n\n if (logalot) {\n console.log(`${lc} metaStoneIbGib... (I: 2b16197478488b329246d22d2dc41423)`);\n console.dir(metaStoneIbGib);\n }\n\n return metaStoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "export const WITNESS_ATOM = 'witness';\nexport const WITNESS_ARG_METADATA_STRING = 'witness_arg';\nexport const WITNESS_RESULT_METADATA_STRING = 'witness_result';\n\nexport const WITNESS_CONTEXT_REL8N_NAME = 'context';\n", "import {\n clone, delay, getExpirationUTCString, getTimestampInTicks,\n getUUID, isExpired, pretty, extractErrorMsg,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { TransformResult, Ib, IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { GIB, IBGIB_DELIMITER } from '@ibgib/ts-gib/dist/V1/constants.mjs'\nimport { IbGib_V1, Rel8n } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Factory_V1 as factory } from '@ibgib/ts-gib/dist/V1/factory.mjs';\nimport { rel8 } from '@ibgib/ts-gib/dist/V1/transforms/rel8.mjs';\nimport { fork } from '@ibgib/ts-gib/dist/V1/transforms/fork.mjs';\nimport { getGib, getGibInfo, } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { APP_REL8N_NAME } from '../app/app-constants.mjs';\nimport {\n GetIbGibOpts, GetIbGibResult, PutIbGibOpts, PutIbGibResult, DeleteIbGibOpts,\n DeleteIbGibResult, SpecialIbGibType, IbGibTimelineUpdateInfo,\n} from '../../common/other/other-types.mjs';\nimport {\n getRootIb, getSpecialConfigKey, getSpecialIbGibIb,\n getSpecialTypeFromIb, getTjpAddr, isSpecial, isTjp_Naive, tagTextToIb\n} from '../../common/other/ibgib-helper.mjs';\nimport { TagData_V1, TagIbGib_V1 } from '../../common/tag/tag-types.mjs';\nimport { BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY, BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY, BOOTSTRAP_IBGIB_ADDR } from './bootstrap/bootstrap-constants.mjs';\nimport {\n SpaceLockScope, IbGibSpaceLockIbGib, SpaceId, IbGibSpaceLockOptions, TxId,\n IbGibSpaceResultIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns, SpaceType, SpaceSubtype, VALID_SPACE_TYPES, VALID_SPACE_SUBTYPES, IbGibSpaceData,\n IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier,\n} from './space-types.mjs';\nimport { getAppIb, } from '../app/app-helper.mjs';\nimport { AppData_V1, AppIbGib_V1 } from '../app/app-types.mjs';\nimport { DEFAULT_CHAT_APP_DATA_V1, DEFAULT_CHAT_APP_REL8NS_V1 } from '../app/chat-app/chat-app-types.mjs';\nimport { DEFAULT_RAW_APP_DATA_V1, DEFAULT_RAW_APP_REL8NS_V1 } from '../app/raw-app/raw-app-types.mjs';\nimport { DEFAULT_TODO_APP_DATA_V1, DEFAULT_TODO_APP_REL8NS_V1, DEFAULT_UUID_TODO_APP } from '../app/todo-app/todo-app-types.mjs';\nimport { IbGibSpaceAny } from './space-base-v1.mjs';\nimport { RootData } from '../../common/root/root-types.mjs';\nimport { IbGibCacheService } from '../../common/cache/cache-types.mjs';\nimport {\n DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE,\n DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS, DEFAULT_SECONDS_VALID_LOCAL,\n DEFAULT_TX_ID_LENGTH, IBGIB_SPACE_NAME_DEFAULT, SPACE_ATOM,\n SPACE_LOCK_IB_TERM, SYNC_SPACE_REL8N_NAME,\n} from './space-constants.mjs';\nimport { DEFAULT_TAG_DESCRIPTION, DEFAULT_TAG_ICON, TAG_REL8N_NAME } from '../../common/tag/tag-constants.mjs';\nimport {\n DEFAULT_ROOT_DESCRIPTION, DEFAULT_ROOT_ICON, DEFAULT_ROOT_REL8N_NAME,\n DEFAULT_ROOT_TEXT, ROOT_REL8N_NAME\n} from '../../common/root/root-constants.mjs';\nimport { ARCHIVE_REL8N_NAME, TRASH_REL8N_NAME } from '../../common/other/other-constants.mjs';\nimport { validateBootstrapIbGib } from './bootstrap/bootstrap-helper.mjs';\nimport { BootstrapData, BootstrapIbGib, BootstrapRel8ns } from './bootstrap/bootstrap-types.mjs';\nimport { newUpMetaStone } from '../../common/meta-stone/meta-stone-helper.mjs';\nimport { WITNESS_ATOM } from '../witness-constants.mjs';\n\nlet logalot = GLOBAL_LOG_A_LOT;\n\n\n/**\n * Two spaces can be equivalent if they point to the same area.\n *\n * @returns true if the \"same\" space\n */\nexport function isSameSpace({\n a,\n b,\n mustHaveSameData,\n}: {\n a: IbGibSpaceAny,\n b: IbGibSpaceAny,\n /**\n * If true, then only same exact internal data will do.\n * Be careful if they have last modified timestamps.\n */\n mustHaveSameData?: boolean,\n}): boolean {\n const lc = `[${isSameSpace.name}]`;\n\n if (!a) { throw new Error(`${lc} a is falsy`) };\n if (!b) { throw new Error(`${lc} b is falsy`) };\n\n // try by data\n if (a.data && JSON.stringify(a.data) === JSON.stringify(b.data)) {\n return true;\n } else if (mustHaveSameData) {\n return false;\n }\n\n // try by uuid\n if (a.data?.uuid && b.data?.uuid) { return a.data!.uuid === b.data!.uuid; }\n\n // try by tjp\n if (a.rel8ns?.tjp?.length === 1 && b.rel8ns?.tjp?.length === 1) {\n return a.rel8ns.tjp[0] === b.rel8ns.tjp[0];\n }\n\n // try by gib (last resort), can't both be falsy or primitive (maybe overkill)\n if (!a.gib && !b.gib) {\n throw new Error(`${lc} Invalid spaces. both a.gib and b.gib are falsy, neither has uuid and neither has tjp.`);\n }\n if (a.gib === GIB && b.gib === GIB) { throw new Error(`${lc} both a and b are primitives`); }\n return a.gib === b.gib;\n}\n\n/**\n * wrapper for dealing with a space.\n *\n * @returns legacy `GetIbGibResult`\n */\nexport async function getFromSpace({\n addr,\n addrs,\n isDna,\n space,\n force,\n}: GetIbGibOpts): Promise<GetIbGibResult> {\n let lc = `[${getFromSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!space) { throw new Error(`space required. (E: 4d188d6c863246f28aa575753a052304)`); }\n if (!addr && (addrs ?? []).length === 0) { throw new Error(`addr or addrs required. (E: 1a0b92564ba942f1ba91a089ac1a2125)`); }\n\n if (addr && (addrs?.length ?? 0) > 0) {\n console.warn(`${lc} both addr and addrs provided, but supposed to be used one or the other. (W: 87226c2ac50e4ea28211334a7b58782f)`);\n if (!addrs!.includes(addr)) { addrs!.push(addr); }\n }\n addrs = (addrs ?? []).length > 0 ? addrs : [addr!];\n\n const argGet = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'get',\n ibGibAddrs: addrs,\n isDna,\n },\n });\n const result = await space.witness(argGet);\n if (result?.data?.success) {\n if (logalot) { console.log(`${lc} got.`) }\n return {\n success: true,\n ibGibs: result.ibGibs,\n rawResultIbGib: result,\n }\n } else {\n if (logalot) { console.log(`${lc} didn't get.`) }\n return {\n success: false,\n errorMsg: result.data?.errors?.join('|') || `${lc} something went wrong. addrs: ${addrs!.join('\\n')} (E: b9e9d5ce0cde4122bfb74f7688db85e0)`,\n rawResultIbGib: result,\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return { errorMsg: error.message, }\n }\n}\n\n/**\n * Wrapper for saving ibgib in a given space.\n *\n * ## warnings\n *\n * The given space doesn't have to work this way.\n * This is a convenience for me ATOW.\n */\nexport async function putInSpace({\n ibGib,\n ibGibs,\n isDna,\n force,\n space,\n}: PutIbGibOpts): Promise<PutIbGibResult> {\n const lc = `[${putInSpace.name}]`;\n try {\n if (!ibGib && (ibGibs ?? []).length === 0) { throw new Error(`ibGib or ibGibs required. (E: e59c4de3695f4dd28c8fe82dbb9c4e90)`); }\n if (!space) { throw new Error(`space required. (E: dd0b7189c67c43c586b905a8ed6f51c9)`); }\n\n if (ibGib && (ibGibs ?? []).length > 0) {\n console.warn(`${lc} Both ibGib and ibGibs is assigned, whereas this is intended to be exclusive one or the other. (W: 4c797835b620445f88e4cba6b5aa3460)`)\n if (!ibGibs!.some(x => x.gib === ibGib.gib)) {\n ibGibs = ibGibs!.concat([ibGib]);\n }\n }\n ibGibs = ibGibs ?? [ibGib!];\n\n if (logalot) { console.log(`${lc} ibGibs.length: ${ibGibs.length}`) }\n const argPutIbGibs = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put', force, isDna,\n ibGibAddrs: ibGibs.map(x => getIbGibAddr({ ibGib: x })),\n },\n ibGibs: ibGibs.concat(),\n });\n const resPutIbGibs = await space.witness(argPutIbGibs);\n if (resPutIbGibs.data?.success) {\n if ((resPutIbGibs.data!.warnings ?? []).length > 0) {\n resPutIbGibs.data!.warnings!.forEach((warning: string) => console.warn(`${lc} ${warning}`));\n }\n return { success: true }\n } else {\n const errorMsg = resPutIbGibs?.data?.errors?.length > 0 ?\n `Error(s) putting in local space:\\n${resPutIbGibs.data.errors.join('\\n')}` :\n '(UNEXPECTED) unknown error putting ibGibs (E: 3d7426d4527243b79c5e55eb25f3fa73)';\n throw new Error(errorMsg);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return { errorMsg: error.message, }\n }\n}\n\n/**\n * Wrapper for removing ibgib from the a given space, else the current space.\n */\nexport async function deleteFromSpace({\n addr,\n isDna,\n space,\n}: DeleteIbGibOpts): Promise<DeleteIbGibResult> {\n let lc = `[${deleteFromSpace.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 40ab3b51e91c4b5eb4f215baeefbcef0)`); }\n if (!space.data) { throw new Error(`space.data required. (E: 0d02c8e85ee143b8bd6a1a1db0d9af1b)`); }\n lc = `${lc}[${space.data.name || 'noname?'}][${space.data.uuid || 'nouuid?'}]`;\n\n const argDel = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'delete',\n ibGibAddrs: [addr],\n isDna,\n },\n });\n const result = await space.witness(argDel);\n if (result.data?.success) {\n return { success: true, }\n } else {\n if (result.data?.warnings?.length > 0) {\n console.warn(`${lc} warnings with delete (${addr}): ${result.data!.warnings!.join('|')}`);\n }\n if (result.data?.addrs?.length > 0) {\n console.warn(`${lc} partial addrs deleted: ${result.data!.addrs!.join('|')}`);\n }\n const errorMsg: string = result.data?.errors?.join('|') || `${lc} something went wrong (E: e397fd09b4a746a3ba3305d6ea0893cb)`;\n if (errorMsg.includes('File does not exist')) {\n if (logalot) { console.log(`${lc} tried to delete file that does not exist. (I: cb5d1348ccbc58bf0bfc95f3006f1e22)`); }\n }\n return { errorMsg }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return { errorMsg: error.message };\n }\n}\n\n/**\n * Convenience function for persisting a transform result, which has\n * a newIbGib and optionally intermediate ibGibs and/or dnas.\n *\n * it persists these ibgibs into the given space, else the current space.\n */\nexport async function persistTransformResult({\n resTransform,\n space,\n force,\n}: {\n resTransform: TransformResult<IbGib_V1>,\n space: IbGibSpaceAny,\n force?: boolean,\n}): Promise<void> {\n const lc = `[${persistTransformResult.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: dc6835614ff1a1b82b179225023ae823)`); }\n if (!space) { throw new Error(`space required. (E: cf94f1d74f1c4561bb88025a2095965b)`); }\n\n const { newIbGib, intermediateIbGibs, dnas } = resTransform;\n const ibGibs = [newIbGib, ...(intermediateIbGibs || [])];\n const argPutIbGibs = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put', force,\n ibGibAddrs: ibGibs.map(x => getIbGibAddr({ ibGib: x })),\n },\n ibGibs: ibGibs.concat(),\n });\n const resPutIbGibs = await space.witness(argPutIbGibs);\n if (resPutIbGibs.data?.success) {\n if (resPutIbGibs.data!.warnings?.length > 0) {\n resPutIbGibs.data!.warnings!.forEach((warning: string) => console.warn(`${lc} ${warning}`));\n }\n } else {\n const errorMsg = resPutIbGibs?.data?.errors?.length > 0 ?\n resPutIbGibs.data.errors.join('\\n') :\n 'unknown error putting ibGibs';\n throw new Error(errorMsg);\n }\n\n if (dnas?.length ?? 0 > 0) {\n const argPutDnas = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put', isDna: true, force,\n ibGibAddrs: dnas!.map(x => getIbGibAddr({ ibGib: x })),\n },\n ibGibs: dnas!.concat(),\n });\n const resPutDnas = await space.witness(argPutDnas);\n if (resPutDnas.data?.success) {\n if (resPutDnas.data!.warnings?.length > 0) {\n resPutDnas.data!.warnings!.forEach((warning: string) => console.warn(`${lc} ${warning}`));\n }\n } else {\n const errorMsg = resPutDnas?.data?.errors?.length > 0 ?\n resPutDnas.data.errors.join('\\n') :\n 'unknown error putting dna ibGibs';\n throw new Error(errorMsg);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: dc6835614ff1a1b82b179225023ae823)`); }\n }\n}\n\nexport async function getSpecialRel8dIbGibs<TIbGib extends IbGib_V1 = IbGib_V1>({\n type,\n rel8nName,\n space,\n}: {\n type: SpecialIbGibType,\n rel8nName: string,\n space: IbGibSpaceAny,\n}): Promise<TIbGib[]> {\n const lc = `[${getSpecialRel8dIbGibs.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f73868a952ac4181a4f90ee6d86cacf3)`); }\n\n let special = await getSpecialIbGib({ type, space });\n if (!special) { throw new Error(`couldn't get special (${type}) (E: a65bef190416479697605be486846731)`) };\n const rel8dAddrs = special.rel8ns ? special.rel8ns[rel8nName] || [] : [];\n const rel8dIbgibs: TIbGib[] = [];\n for (let i = 0; i < rel8dAddrs.length; i++) {\n const addr = rel8dAddrs[i];\n let resGet = await getFromSpace({ addr, space });\n if (resGet.success && resGet.ibGibs?.length === 1) {\n rel8dIbgibs.push(resGet.ibGibs[0] as TIbGib);\n } else {\n throw new Error(`couldn't get addr: ${addr} (E: 76ef256ee80149ab860c5786484b0e89)`);\n }\n }\n return rel8dIbgibs;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Gets one of the app's special ibGibs, e.g., TagsIbGib.\n *\n * When initializing tags, this will generate some boilerplate tags.\n * I'm going to be doing roots here also, and who knows what else, but each\n * one will have its own initialize specifics.\n *\n * @param initialize initialize (i.e. create) ONLY IF IbGib not found. Used for initializing app (first run).\n *\n * @see {@link createSpecial}\n * @see {@link createSpecial_Tags}\n */\nexport async function getSpecialIbGib({\n type,\n initialize,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n fnGetInitializing,\n fnSetInitializing,\n dontWarnIfNotExist,\n}: {\n type: SpecialIbGibType,\n initialize?: boolean,\n space: IbGibSpaceAny,\n /**\n * Only required if `initialize` is true.\n */\n zeroSpace?: IbGibSpaceAny,\n /**\n * Only required if `initialize` is true.\n */\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n /**\n * Only required if `initialize` is true.\n */\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n /**\n * Initialization lock getter function.\n */\n fnGetInitializing?: () => boolean,\n /**\n * Initialization lock setter function.\n *\n * Because we don't want to initialize while we're initializing.\n */\n fnSetInitializing?: (x: boolean) => void,\n /**\n * if true, won't warn about non-existent/non-initialized things.\n * useful if you are just checking to see if a special ibgib exists.\n */\n dontWarnIfNotExist?: boolean,\n}): Promise<IbGib_V1 | null> {\n const lc = `[${getSpecialIbGib.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: d454b31d58764a9bb9c4e47fb5ef38b5)`); }\n\n let key = getSpecialConfigKey({ type });\n let addr = await getConfigAddr({\n key, space,\n dontWarn: dontWarnIfNotExist || !!initialize // dont warn if we're initializing\n });\n\n if (!addr) {\n if (initialize && (!fnGetInitializing || !fnSetInitializing)) { throw new Error(`if initialize, you must provide fnGetInitializeLock & fnSetInitializeLock. (E: 8eb322625d0c4538be089800882487de)`); }\n if (initialize && !fnGetInitializing!()) {\n fnSetInitializing!(true);\n try {\n if (!zeroSpace) { throw new Error(`zeroSpace required when 'initialize' truthy (E: 8582c92c637f90c9b2dbe0ec8355b523)`); }\n addr = await createSpecial({ type, space, zeroSpace: zeroSpace!, fnBroadcast, fnUpdateBootstrap }) ?? undefined;\n } catch (error) {\n console.error(`${lc} error initializing: ${error.message}`);\n } finally {\n fnSetInitializing!(false);\n }\n }\n if (!addr) {\n if (fnGetInitializing && fnGetInitializing()) {\n console.warn(`${lc} couldn't get addr, but we're still initializing...`);\n return null;\n } else {\n throw new Error(`Special address not in config and couldn't initialize it either. (E: d8ebdc9eaaa640b99cd206f132962c93)`);\n }\n }\n }\n\n if (logalot) { console.log(`${lc} getting addr: ${addr}`); }\n\n let resSpecial = await getFromSpace({ addr, space });\n\n // I'm putting in this check in case we're getting a meta that wasn't\n // saved into the meta folder.\n if (!resSpecial.success) {\n resSpecial = await getFromSpace({ addr, space });\n if (resSpecial.success) {\n console.warn(`${lc} special ibgib was not stored in meta folder...putting in meta folder now for the future (W: e6f5571fd98c449bb2809359be5057cc)`);\n const resPutInMeta = await putInSpace({ ibGib: resSpecial!.ibGibs![0], space });\n if (!resPutInMeta.success) {\n console.warn(`${lc} (UNEXPECTED) tried to put special in meta but success was false? (W: b934b53571c24057af172c790e6a7240)`)\n }\n }\n }\n if (!resSpecial.success) { throw new Error(resSpecial.errorMsg); }\n if (resSpecial.ibGibs?.length !== 1) { throw new Error(`no ibGib in result (E: 3a42abdddc3648e292d63dc45c560064)`); }\n const specialIbGib = resSpecial.ibGibs[0];\n\n // I'm putting this check in here because it's bad not to have the\n // latest special associated with a space. eventually this shouldn't be\n // necessary.\n let resLatest = await getLatestAddrs({ ibGibs: [specialIbGib], space });\n if (resLatest?.data?.success && resLatest.data.addrs?.length === 1) {\n let specialAddr = getIbGibAddr({ ibGib: specialIbGib });\n let latestAddr = resLatest.data.addrs[0];\n if (latestAddr !== specialAddr) {\n console.warn(`${lc} latest addr is not the one associated with the local space.\\nspecialAddr: ${specialAddr}\\nlatestAddr: ${latestAddr} (W: 141b69dc3c414efc9645bb76fcf12df9)`)\n }\n }\n\n return specialIbGib;\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n /**\n * error code found in preceding try block (just do a find on it).\n */\n const notFoundErrorCode = 'd8ebdc9eaaa640b99cd206f132962c93';\n if (emsg.includes(notFoundErrorCode) && dontWarnIfNotExist) {\n // don't log error, it's expected\n } else {\n console.error(emsg);\n }\n return null;\n }\n}\n\n/**\n * Gets a config addr from the current space via the given key\n * as the space's rel8n name.\n *\n * For example, for `key = tags`, a space may look like:\n *\n * ```json\n * {\n * ib: space xyz,\n * gib: e89ff8a1c4954db28432007615a78952,\n * rel8ns: {\n * past: [space xyz^21cb29cc353f45a491d2b49ff2f130db],\n * ancestor: [space^gib],\n * tags: [tags^99b388355f8f4a979ca30ba284d3a686], // <<< rel8n with name specified by key\n * }\n * }\n * ```\n *\n * @param key config key\n * @returns addr in config if exists, else undefined\n */\nexport async function getConfigAddr({\n key,\n space,\n dontWarn,\n}: {\n key: string,\n space: IbGibSpaceAny,\n /**\n * if true, won't warn about non-existent/non-initialized things.\n * useful if you are just checking to see if a special ibgib exists.\n */\n dontWarn?: boolean,\n}): Promise<string | undefined> {\n const lc = `[${getConfigAddr.name}](${key})`;\n try {\n if (logalot) { console.log(`${lc} getting... (I: 43e7bfc2515d45e5af8767b9a85b248e)`) }\n\n if (!space) { throw new Error(`space required. (E: 4f135d4276e64054ba21aeb9c304ecec)`); }\n\n if (!space.rel8ns) {\n if (logalot || !dontWarn) { console.warn(`${lc} space.rel8ns falsy. (W: 7c642259fbf547dbaa1b2fdf0115f6ef)`); }\n return undefined;\n }\n if (!space.rel8ns[key]) {\n if (logalot || !dontWarn) { console.warn(`${lc} space.rel8ns[${key}] falsy. (W: 3c1c49b9987b45cc96dd78b808f98e91)`); }\n return undefined;\n }\n if (space.rel8ns[key]!.length === 1) {\n if (logalot) { console.log(`${lc} got (I: f13e71b693d5404c9535bda8ff0cc6a9)`); }\n return space.rel8ns![key]![0];\n } else if (space.rel8ns[key]!.length > 1) {\n if (logalot || !dontWarn) { console.warn(`${lc} more than one config addr with ${key} rel8n. (W: 102f63eb74904bcfaac2eaf778043205)`) }\n return space.rel8ns![key]![0];\n } else {\n if (logalot) { console.log(`${lc} didn't find (I: 1163e6ac60194d25b3f24881650edfad)`); }\n // key not found or?\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n}\n\nexport async function setConfigAddr({\n key,\n addr,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n}: {\n key: string,\n addr: string,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n}): Promise<IbGibSpaceAny> {\n const lc = `[${setConfigAddr.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: c28b663c991d44419aef1026cc689636)`); }\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: d3707ae5265d464891ad216f64be6184)`); }\n\n // rel8 the `addr` to the current space via rel8n named `key`\n // note that since we are replacing the pointer, we include the key\n // in `linkedRel8ns` which will keep only the most recent\n const rel8nsToAddByAddr = { [key]: [addr] };\n const resNewSpace = await rel8({\n src: space.toIbGibDto(),\n dna: false,\n linkedRel8ns: [\"past\", \"ancestor\", key], // we only want the most recent key address\n rel8nsToAddByAddr,\n nCounter: true,\n });\n\n if (!resNewSpace.newIbGib) { throw new Error(`create new space failed.`); }\n\n // persist the new space in both default space and its own space\n // (will actually have the space witness its future self interestingly\n // enough...perhaps should have the new space witness itself instead\n\n // witness in the default zero space\n // in refactoring, may have to make this optional...hmm\n await persistTransformResult({ resTransform: resNewSpace, space: zeroSpace });\n\n // witness in the given space\n await persistTransformResult({ resTransform: resNewSpace, space });\n\n // going to update the bootstrap^gib with the new space address, but first...\n const newSpace = (resNewSpace.newIbGib as IbGibSpaceAny);\n\n // ...must update the original space reference any time we change it.\n // messy atm...\n await space.loadIbGibDto(newSpace);\n\n // ...now update so the proper space (config) loads on next app start\n if (fnUpdateBootstrap) {\n await fnUpdateBootstrap(newSpace);\n } else {\n console.warn(`${lc} fnUpdateBootstrap is falsy. (W: 9fb874de2b19454dac18645e61ac463f)`);\n }\n\n return newSpace;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport async function getCurrentRoot({\n space,\n}: {\n space: IbGibSpaceAny,\n}): Promise<IbGib_V1<RootData> | undefined> {\n const lc = `[${getCurrentRoot.name}]`;\n\n try {\n if (!space) { throw new Error(`space required. (E: f0d546101fba4c169256158114ab3c56)`); }\n\n const roots = await getSpecialIbGib({ type: \"roots\", space });\n if (!roots) { throw new Error(`Roots not initialized. (E: 89b1ba12ed12416aac41cef9fdaf1fc2)`); }\n if (!roots.rel8ns) { throw new Error(`Roots not initialized properly. No rel8ns. (E: 8513a07cf530484db9521a2a3a27b7f6)`); }\n if (!roots.rel8ns.current) { throw new Error(`Roots not initialized properly. No current root. (E: 459c3a007a30486d96fb8d83f696e239)`); }\n if (roots.rel8ns.current.length === 0) { throw new Error(`Invalid Roots: empty current root rel8n. (E: bede5864090440bca01ea7ab7fd107d6)`); }\n if (roots.rel8ns.current.length > 1) { throw new Error(`Invalid Roots: multiple current roots selected. (E: 97561acbf63a48ecaa037697bd26555a)`); }\n\n const currentRootAddr = roots.rel8ns.current[0]!;\n const resCurrentRoot =\n await getFromSpace({ addr: currentRootAddr, space });\n if (resCurrentRoot.ibGibs?.length === 1) {\n return resCurrentRoot.ibGibs![0] as IbGib_V1<RootData>;\n } else {\n throw new Error(`could not get current root. addr: ${currentRootAddr}`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n}\n\nexport async function setCurrentRoot({\n root,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n root: IbGib_V1<RootData>,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n const lc = `[${setCurrentRoot.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 7f16e845a80fe95d28923e4170f0c825)`); }\n if (!root) { throw new Error(`root required.`); }\n\n if (!space) { throw new Error(`space required. (E: 186af2731c5342a78b063a0a4346f3db)`); }\n\n const rootAddr = getIbGibAddr({ ibGib: root });\n\n // get the roots and update its \"current\" rel8n\n const roots = await getSpecialIbGib({ type: \"roots\", space });\n if (!roots) { throw new Error(`Roots not initialized. (E: a8232b9afac89d0d189534480b7a9825)`); }\n\n // we'll rel8 current with a linkedRel8n, thus ensuring a maximum of only\n // one rel8d addr (the one we're adding here)\n const rel8nsToAddByAddr = { current: [rootAddr] };\n const resNewRoots = await rel8({\n src: roots,\n dna: false,\n linkedRel8ns: [\"past\", \"ancestor\", \"current\"], // current here ensures only 1 rel8n\n rel8nsToAddByAddr,\n nCounter: true,\n });\n await persistTransformResult({ resTransform: resNewRoots, space });\n\n const configKey = getSpecialConfigKey({ type: \"roots\" });\n const newRoots = resNewRoots.newIbGib;\n const newRootsAddr = getIbGibAddr({ ibGib: newRoots });\n await setConfigAddr({ key: configKey, addr: newRootsAddr, space, zeroSpace, fnUpdateBootstrap });\n await registerNewIbGib({ ibGib: newRoots, space, fnBroadcast, });\n\n // how to let others know roots has changed?\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: 7f16e845a80fe95d28923e4170f0c825)`); }\n }\n}\n\n/**\n * Every tjp should be related to one of the roots in a space.\n *\n * You should NOT relate every ibgib frame of a given ibGib.\n */\nexport async function rel8ToCurrentRoot({\n ibGib,\n linked,\n rel8nName,\n space,\n fnBroadcast,\n zeroSpace,\n fnUpdateBootstrap,\n}: {\n ibGib: IbGib_V1,\n linked?: boolean,\n rel8nName?: string,\n space: IbGibSpaceAny,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n}): Promise<void> {\n const lc = `[${rel8ToCurrentRoot.name}]`;\n\n try {\n if (!space) { throw new Error(`space required. (E: f2758eab3bb844d2b749515672d9e392)`); }\n if (!ibGib) { throw new Error(`ibGib required (E: f1bfd67754a7271553f4af544d30bc22)`); }\n\n let currentRoot = await getCurrentRoot({ space });\n if (!currentRoot) { throw new Error('currentRoot undefined (E: 5c2d84dafc664808866008f6eb535750'); }\n\n // only relate the tjp to roots and use the latest index ibgib to have\n // the reference to the latest ibgib in the space.\n const tjpAddr = getTjpAddr({ ibGib, defaultIfNone: \"incomingAddr\" });\n const ibGibAddr = getIbGibAddr({ ibGib });\n\n // check to see if it's already rel8d. If so, we're done.\n if (rel8nName && tjpAddr &&\n currentRoot.rel8ns &&\n currentRoot.rel8ns[rel8nName] &&\n currentRoot.rel8ns[rel8nName]!.includes(tjpAddr)) {\n // already rel8d\n return;\n }\n\n rel8nName = rel8nName || DEFAULT_ROOT_REL8N_NAME;\n\n // we only need to add the ibgib itself to the root, not the tjp\n // and not any dependent ibgibs. ...wakka doodle.\n const resNewRoot = await rel8({\n src: currentRoot,\n dna: false,\n linkedRel8ns: linked ? [\"past\", \"ancestor\", rel8nName] : [\"past\", \"ancestor\"],\n rel8nsToAddByAddr: { [rel8nName]: [ibGibAddr] },\n nCounter: true,\n });\n await persistTransformResult({ resTransform: resNewRoot, space });\n const newRoot = resNewRoot.newIbGib as IbGib_V1<RootData>;\n const newRootAddr = getIbGibAddr({ ibGib: newRoot });\n if (logalot) { console.log(`${lc} updating _currentRoot root. newRootAddr: ${newRootAddr}`); }\n await registerNewIbGib({ ibGib: newRoot, space, fnBroadcast, });\n await setCurrentRoot({ root: newRoot, space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return;\n }\n}\n\n/**\n * used atow (11/2023) for latest ibgib indexing.\n * i dont know any use cases right now to use this explicitly.\n * used in {@link registerNewIbGib}\n */\nexport async function createAndSaveNewMetaStone({\n targetIbGib,\n space,\n}: {\n targetIbGib: IbGib_V1,\n space: IbGibSpaceAny,\n}): Promise<void> {\n const lc = `[${createAndSaveNewMetaStone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 291638372117dbc983b4b7cbd8f52123)`); }\n const metaStone = await newUpMetaStone({ targetIbGib });\n const resPutMetaStone = await putInSpace({ ibGib: metaStone, space });\n if (!resPutMetaStone.success) { throw new Error(`error putting metaStone in space. error: ${resPutMetaStone.errorMsg ?? '[unknown error (E: 45f700f4f1ff463ca8f5353c8e796ac7)]'} (E: 4c25379e66365055e3e423561a7d6123)`); }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Used for tracking tjpAddr -> latest ibGibAddr.\n *\n *\n * Call this when you create a new ibGib.\n *\n * Need to put this in another service at some point, but crunch crunch\n * like pacman's lunch.\n *\n * ## notes\n *\n * * atow (11/2023)the new implementation of this creates a metastone for\n * the incoming ibgib and broadcasts if a timeline is involved.\n * * double-checks if previous latest addr is actually older.\n */\nexport async function registerNewIbGib({\n ibGib,\n space,\n fnBroadcast,\n}: {\n ibGib: IbGib_V1,\n space: IbGibSpaceAny,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n let lc = `[${registerNewIbGib.name}]`;\n let initialLogalot = logalot;\n // logalot = true;\n try {\n const ibGibAddr: IbGibAddr = getIbGibAddr({ ibGib });\n lc = `${lc}[${ibGibAddr}]`;\n\n if (!space) { throw new Error(`space required. (E: ea0c03256f8a4062b460aa4de11f1e3e)`); }\n\n if (logalot) { console.log(`${lc} starting...`); }\n\n // we only need to register as latest if there is a timeline involved.\n let gibInfo = getGibInfo({ ibGibAddr });\n if (!gibInfo.tjpGib && !ibGib.data?.isTjp) {\n if (logalot) { console.log(`${lc} incoming ibGib has no timeline, so no broadcast. still going to create a metastone for it and return early. (I: 649752e3b1be0e0ceb078e0ec2a84f23)`); }\n await createAndSaveNewMetaStone({ targetIbGib: ibGib, space });\n return; /* <<<< returns early */\n }\n\n let tjpAddr = getTjpAddr({ ibGib, defaultIfNone: 'undefined' });\n if (!tjpAddr) {\n // get tjp information. used in multiple places in the rest of this fn\n let tjp = ibGib.data?.isTjp ? ibGib : await getTjpIbGib({ ibGib, space });\n if (!tjp) {\n console.warn(`${lc} tjp not found for ${ibGibAddr}? Should at least just be the ibGib's address itself. (W: d9b570e5bf6d4312bc7d9249ed3bbaad)`);\n tjp = ibGib;\n }\n tjpAddr = getIbGibAddr({ ibGib: tjp });\n }\n if (!tjpAddr) { throw new Error(`(UNEXPECTED) tjpAddr falsy? should be guaranteed at this point. (E: 39aafb70bc3c6d70b6d2cf8882311223)`); }\n\n /**\n * either we're adding the given ibGib, replacing the existing with the\n * ibGib, or doing nothing. We can do this with our current vars in a\n * closure at this point.\n */\n const replaceLatest: () => Promise<void> = async () => {\n if (logalot) { console.log(`${lc} adding/replacing latest. tjp: ${tjpAddr} (I: 7f848da003a2436089fd6f044d96bb42)`); }\n\n await createAndSaveNewMetaStone({ targetIbGib: ibGib, space });\n\n // broadcast if available\n if (fnBroadcast) {\n if (logalot) { console.log(`${lc} fnBroadcast is true...(I: 0e3b561fb5474a0598b5c6d698df5e1f)`) }\n // queue it up in event loop, as this spins off\n setTimeout(() => {\n if (logalot) { console.log(`${lc} broadcasting... (I: 61785937be0346f0959d476d7267ab24)`) }\n fnBroadcast({\n ib: 'IbGibTimelineUpdateInfo',\n tjpAddr,\n latestAddr: ibGibAddr,\n latestIbGib: ibGib\n });\n });\n }\n }\n\n if (ibGib.data?.isTjp) {\n // this is the temporal junction point, so we know it's new...but\n // perhaps it has already been registered? regardless, shouldn't be\n // a big deal if multiple metastones are made for the same tjp, and\n // there is a tradeoff here. either we spend extra processing time\n // each time to check to be sure there isn't already one there\n // (rare) or we just live with the possibility of some having\n // multiple metastones created (also rare).\n if (logalot) { console.log(`${lc} ibGib.data?.isTjp true. replacingLatest and returning early. (I: 02c626e006668291550e278b461bcb23)`); }\n await replaceLatest();\n return; /* <<<< returns early */\n }\n\n // there is a tjp/timeline involved. check to see if the new ibgib is\n // actually new.\n if (logalot) { console.log(`${lc} ibGib.data?.isTjp is falsy. (I: 84940e3a9eff869c9474b7b92b864b23)`); }\n const resLatest = await getLatestAddrs({ ibGibs: [ibGib], space, });\n if (!resLatest.data) { throw new Error(`(UNEXPECTED) resLatest.data falsy? (E: af3d3914d96adcc5525e4db83cc5d223)`); }\n let { success, latestAddrsMap } = resLatest.data;\n if (!success) {\n let { errors } = resLatest.data;\n errors ??= ['[unknown error (E: 344857f1853641aa842cea3931f90428)]'];\n throw new Error(`resLatest.success falsy. errors: ${pretty(errors)}. addr: ${ibGibAddr} (E: b66721da6e1ef9ac4f4089e86c059323)`);\n }\n\n // #region validate expectations of resulting latestAddrsMap\n if (!latestAddrsMap) { throw new Error(`(UNEXPECTED) latestAddrsMap falsy but success truthy? (E: c34caff7a256503575ff3ff491dec823)`); }\n let keysLatestAddrsMap = Object.keys(latestAddrsMap);\n if (keysLatestAddrsMap.length !== 1) { throw new Error(`(UNEXPECTED) latestAddrsMap size isn't 1? (E: e11ffc2c18d473745b5bbfc3fe5e3a23)`); }\n if (keysLatestAddrsMap[0] !== ibGibAddr) { throw new Error(`(UNEXPECTED) latestAddrsMap has 1 key (correct) but the key isn't the incoming ibGibAddr? (incorrect). incoming ibGibAddr: ${ibGibAddr}. key found: ${keysLatestAddrsMap[0]} (E: 82d79a95d2d7de90eae9db571a360f23)`); }\n // #endregion validate expectations of resulting latestAddrsMap\n\n\n if (logalot) {\n console.log(`${lc} valid latestAddrsMap. console.dir(latestAddrsMap)... (I: e24de41622cabbef375172c3017cfd23)`);\n console.dir(latestAddrsMap);\n }\n const existingLatestAddr = latestAddrsMap[ibGibAddr];\n if (existingLatestAddr) {\n if (existingLatestAddr === ibGibAddr) {\n // latest addr is the same as the incoming addr may indicate:\n // 1. NOT NEW if it's already registered.\n // 2. NEW but not necessarily registered (with new impl as of 11/2023).\n\n // at the very least we can replace the latest (which saves a\n // new metastone) and the broadcast subscribers can do\n // additional checking if the address is actually new to them or\n // not. (I think it's different logic so other things may break)\n if (logalot) { console.log(`${lc} no other found. possible idempotent replacement. addr: ${ibGibAddr} (I: 7f5bd5d3391be95919240f0e97976e22)`); }\n await replaceLatest();\n return; /* <<<< returns early */\n } else {\n // different addr found, then YES the incoming ibGibAddr is expected\n // to be NEW (note that the incoming ibgib may indeed be older but\n // somehow the register new has gotten out of whack and this should be\n // defensively checked elsewhere as needed). So broadcast that there is\n // a new ibGib if there is a tjp involved.\n\n if (logalot) { console.log(`${lc} different addr found. incoming ibgib addr is newer. existingLatestAddr: ${existingLatestAddr}. incoming addr: ${ibGibAddr} (I: 6cadf13f82aabeb71d76babf1813e623)`); }\n\n // double check that the existing ibGib actually is older. once that is\n // determined, then we'll execute the replaceLatest\n\n // not the latest or not registered, so get the full existing latest\n // ibgib and analyze to see if the incoming ibgib is indeed newer\n let resExistingLatest = await getFromSpace({ addr: existingLatestAddr, space });\n if (!resExistingLatest.success || resExistingLatest.ibGibs?.length !== 1) {\n console.error(`Didn't find existing latest ibGib (${existingLatestAddr}). I haven't implemented more robust multi-node/distributed strategies for this scenario yet. so we are going ahead with setting the incoming ibgib as the latest in the timeline. (E: 10f6cca6e5ef45bfacbfe48f652e2102)`);\n await replaceLatest();\n return; /* <<<< returns early */\n }\n const existingLatestIbGib = resExistingLatest.ibGibs![0];\n\n // if there is an nCounter, then we can go by that. Otherwise, we'll\n // try to brute force \"latest\" comparison\n const ibGibHasNCounter =\n typeof ibGib.data?.n === 'number' &&\n ibGib.data!.n! >= 0;\n if (ibGibHasNCounter) {\n // #region ibGib.data.n counter method\n if (logalot) { console.log(`found ibGib.data.n (version counter), using this to determine latest ibGib: ${ibGib.data!.n!}`); }\n const n_ibGib = (ibGib.data!.n! as number);\n\n const existingLatestHasNCounter =\n typeof existingLatestIbGib.data?.n === 'number' &&\n existingLatestIbGib.data!.n! >= 0;\n\n if (existingLatestHasNCounter) {\n // both have counters, so compare by those.\n const n_existingLatest = (existingLatestIbGib.data!.n! as number);\n if (n_ibGib > n_existingLatest) {\n // is newer\n if (logalot) { console.log(`${lc} is newer (I: 040d05ac2032f08c7fd0c4d8b2887323)`); }\n await replaceLatest();\n } else {\n // not newer\n if (logalot) { console.log(`is not newer, so we don't need to do anything else. (I: 14c25dc3314748dc909d61b77eb64354)`) }\n console.warn(`${lc} incoming ibGib (${ibGibAddr}) is NOT NEWER than existing latest (${existingLatestAddr}). multiple branches for the same timeline? ignoring incoming ibGibAddr. n_ibGib: ${n_ibGib}. n_existingLatest: ${n_existingLatest}. space.ib: ${space.ib} (W: 057baadca494473dabb26fb4fb879774)`)\n return; /* <<<< returns early */\n }\n } else {\n // only the new one has the counter, so that wins by\n // default. this is common when existingLatestIbGib is a\n // tjp and the ibGib we're registering is n === 0\n if (existingLatestIbGib.data?.isTjp && ibGib.data!.n === 0) {\n // normal situation\n await replaceLatest();\n } else {\n console.warn(`${lc} (UNEXPECTED) only existingLatestIbGib (isTjp: ${existingLatestIbGib.data?.isTjp}) has a data.n counter? ibGib.data.n: ${ibGib.data!.n}. usually this only happens when existing latest is a tjp and the new ibGib we are registering is n === 0. This is falsy in this instance though. We will go ahead and replace the latest with the new one, but this is an anomalous state. (W: 73d08aea17ad4e1481a5f97e2556a878)`)\n console.log(`${lc} console.dir(existingLatestIbGib)... (I: 9ef7962d9cc74f1eb0409e5caf98e915)`);\n console.dir(existingLatestIbGib);\n console.log(`${lc} console.dir(ibGib)... (I: 9ef7962d9cc74f1eb0409e5caf98e915)`);\n console.dir(ibGib);\n await replaceLatest();\n }\n }\n // #endregion\n\n } else {\n if (logalot) { console.log(`${lc} no nCounter found. Trying brute force method.`); }\n // #region brute force latest\n let latestAddr = await getLatestAddr_Brute({\n ibGib, ibGibAddr,\n existingLatest: existingLatestIbGib, existingLatestAddr,\n tjpAddr,\n space,\n });\n if (latestAddr === ibGibAddr) {\n await replaceLatest();\n } else {\n return; /* <<<< returns early */\n }\n // #endregion\n }\n }\n } else {\n // if latestAddr is null (no address is found), the incoming ibGib\n // timeline (or ibGib itself if it's a stone) has not been found at all\n // yet so YES the incoming ibGib is NEW\n if (existingLatestAddr === null) {\n if (logalot) { console.log(`${lc} no existing tjp mapping so incoming ibgib is considered new to this space. ibGib addr: ${ibGibAddr} (I: 4f2bbc32b31e4fa982d95b3a785db82f)`); }\n await replaceLatest();\n return; /* <<<< returns early */\n } else {\n // should we just warn?\n throw new Error(`(UNEXPECTED) latestAddr is falsy but not null? the getLatestAddrs impl in the space should be guaranteed to provide either the incoming ibgib addr, the latest addr (if exists), or null if not found. (E: 3159dd531c0bc0efc1ece116adf28923)`);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n logalot = initialLogalot;\n }\n}\n\n/**\n * Performs a rel8 transform on the special ibgib corresponding to the incoming\n * `type`.\n *\n * ## special ibgibs\n *\n * much metadata configuration is stored via \"special\" ibgibs. Most of these are\n * tracked in a space's ibgib directly, and the space itself is tracked in the\n * bootstrap. So when storing configuration data, I usually create a new special\n * ibgib. this function performs the plumbing for the rel8 transform related to\n * that special ibgib.\n *\n * ## notes\n *\n * * special ibgib must exist in the space, i.e. previously initialized\n * * i'm using this atm for mainly the local ionic space, but sometimes\n * might be good in sync space, i dunno at this point.\n * * I've migrated a lot of local space behavior into this space-agnostic file.\n *\n * @returns new special ibgib addr\n */\nexport async function rel8ToSpecialIbGib({\n type,\n rel8nName,\n ibGibsToRel8,\n ibGibsToUnRel8,\n addrsToUnRel8,\n linked,\n severPast,\n deletePreviousSpecialIbGib,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n /**\n * the \"name\" of the special ibgib.\n *\n * This will drive deterministically what the special ibgib's `ib` will be,\n * among other things.\n */\n type: SpecialIbGibType,\n /**\n * The rel8nName by which to rel8 the target incoming `ibGibsToRel8`.\n */\n rel8nName: string,\n /**\n * multiple ibgibs to rel8\n */\n ibGibsToRel8?: IbGib_V1[],\n /**\n * multiple ibgibs to UNrel8.\n * YOU CANNOT SET BOTH {@link ibGibsToUnRel8} AND {@link addrsToUnRel8}\n * There is no technical reason for this, I'm just too tired to implement\n * yagni overhead.\n * @see {@link addrsToUnRel8}\n */\n ibGibsToUnRel8?: IbGib_V1[],\n /**\n * alternatively just specify addrs to unrel8.\n * YOU CANNOT SET BOTH {@link ibGibsToUnRel8} AND {@link addrsToUnRel8}\n * There is no technical reason for this, I'm just too tired to implement\n * yagni overhead.\n * @see {@link ibGibsToUnRel8}\n */\n addrsToUnRel8?: IbGibAddr[],\n /**\n * If linked, then the rel8nName will only contain one address, i.e. the\n * last rel8d ibgib's address.\n *\n * This depends on your use case.\n */\n linked?: boolean,\n /**\n * Clears out the special.rel8ns.past array to an empty array.\n *\n * {@see deletePreviousSpecialIbGib} for driving use case.\n */\n severPast?: boolean,\n /**\n * Deletes the previous special ibGib.\n *\n * ## driving use case\n *\n * the latest ibGib is one that is completely ephemeral. It doesn't get attached\n * to the current root, and it only has the current instance. So we don't want to\n * keep around past incarnations.\n */\n deletePreviousSpecialIbGib?: boolean,\n /**\n * The space in which the special ibgib resides.\n */\n space: IbGibSpaceAny,\n /**\n * The default zero space that contains metaspace information, i.e.\n * bootstrap ibgib, space ibgibs, etc.\n */\n zeroSpace: IbGibSpaceAny,\n /**\n * The function by which to update the bootstrap ibgib.\n *\n * This is necessary, because when you update a special ibgib,\n * the address of that special ibgib must be updated in the given\n * `space`. This will require an update to the space's address, which\n * itself is tracked in the bootstrap ibgib.\n */\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n /**\n * Use this if you want to broadcast the new space's address after this\n * function performs the rel8 transform.\n */\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr> {\n const lc = `[${rel8ToSpecialIbGib.name}](type:${type},rel8nName:${rel8nName})`;\n try {\n if (!space) { throw new Error(`space required. (E: 956192eea28047eba6dad81620bb96fb)`); }\n if ((ibGibsToRel8 ?? []).length === 0 &&\n (ibGibsToUnRel8 ?? []).length === 0 &&\n (addrsToUnRel8 ?? []).length === 0\n ) {\n throw new Error(`either ibGibsToRel8 or ibGibsToUnRel8 required. (E: 5add49c8e46a54e2c6b057c22646a822)`);\n }\n if ((ibGibsToUnRel8 ?? []).length > 0 && (addrsToUnRel8 ?? []).length > 0) {\n throw new Error(`can't provide both ibGibsToUnRel8 and addrsToUnRel8. There isn't a technical reason but I'm too tired right now to implement the overhead to enable this atow (05/2025). (E: 31ef66be26349cfe1b1f352389b99425)`);\n }\n\n const addrsToRel8 = ibGibsToRel8?.map(ibGib => getIbGibAddr({ ibGib }));\n addrsToUnRel8 ??= ibGibsToUnRel8?.map(ibGib => getIbGibAddr({ ibGib }));\n\n // get the special ibgib\n const configKey = getSpecialConfigKey({ type });\n let specialAddr =\n // type === SpecialIbGibType.latest ? // latest special ibgib addr is constant\n // getSpecialIbGibAddr({ type }) :\n await getConfigAddr({ key: configKey, space });\n if (!specialAddr) { throw new Error(`specialAddr not found (E: 680dfd1caa3e4d7cb0f593b893a10f0d)`) };\n let resGetSpecial = await getFromSpace({ addr: specialAddr, space });\n if (!resGetSpecial.success) { throw new Error(`couldn't get special (E: 897f7671d2184515866c5a675d33b3dc)`) }\n if (!resGetSpecial.ibGibs) { throw new Error(`resGetSpecial.ibGibs falsy (E: 2405dd295b2444d88503f7731796a5a0)`) }\n if (resGetSpecial.ibGibs!.length !== 1) { throw new Error(`resGetSpecial.ibGibs count is not 1 (${resGetSpecial.ibGibs!.length}) (E: b4547789016a4729af30cd972a4ca4ab)`) }\n\n const oldSpecialIbGib = resGetSpecial.ibGibs![0];\n\n // execute the rel8 transform on the special ibgib.\n const resNewSpecial = await rel8({\n src: oldSpecialIbGib,\n rel8nsToAddByAddr: addrsToRel8 ? { [rel8nName]: addrsToRel8 } : undefined,\n rel8nsToRemoveByAddr: addrsToUnRel8 ? { [rel8nName]: addrsToUnRel8 } : undefined,\n dna: false,\n linkedRel8ns: linked ? [Rel8n.past, rel8nName] : [Rel8n.past],\n nCounter: true,\n });\n const newSpecialIbGib = resNewSpecial.newIbGib;\n\n // sever\n if (severPast) {\n if (resNewSpecial.intermediateIbGibs) { throw new Error('new special creates intermediate ibgibs. so severing past is harder. (E: b580c0c56253494192e9c62212ee187d)'); }\n newSpecialIbGib.rel8ns!.past = [];\n newSpecialIbGib.gib = await getGib({ ibGib: newSpecialIbGib });\n }\n\n // // special ibgib latest index is always the same address\n // if (type === SpecialIbGibType.latest) {\n // newSpecialIbGib.gib = GIB;\n // }\n\n // persist\n await persistTransformResult({ resTransform: resNewSpecial, space });\n\n // return the new special address (not the incoming new ibGib)\n const newSpecialAddr = getIbGibAddr({ ibGib: newSpecialIbGib });\n const specialTjpAddr = getTjpAddr({ ibGib: newSpecialIbGib });\n\n // update the space ibgib which contains the special/config information\n // if (type !== SpecialIbGibType.latest) {\n await setConfigAddr({ key: configKey, addr: newSpecialAddr, space, zeroSpace, fnUpdateBootstrap });\n // }\n\n // delete if required, only after updating config with the new special addr.\n // if (deletePreviousSpecialIbGib && type !== SpecialIbGibType.latest) {\n if (deletePreviousSpecialIbGib) {\n await deleteFromSpace({ addr: specialAddr, space });\n }\n\n await registerNewIbGib({ ibGib: newSpecialIbGib, fnBroadcast, space, });\n\n // is this necessary? no i don't think so, as the above registerNewIbGib\n // already has this dispatch\n // if (fnBroadcast && specialTjpAddr && getIbAndGib({ ibGibAddr: specialTjpAddr }).gib !== GIB) {\n // fnBroadcast({\n // ib: 'IbGibTimelineUpdateInfo',\n // tjpAddr: specialTjpAddr,\n // latestIbGib: newSpecialIbGib,\n // latestAddr: newSpecialAddr,\n // });\n // }\n\n return newSpecialAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport async function getTjpIbGib({\n ibGib,\n naive = true,\n space,\n}: {\n ibGib: IbGib_V1<any>,\n naive?: boolean,\n space: IbGibSpaceAny,\n}): Promise<IbGib_V1<any> | undefined> {\n const lc = `[${getTjpIbGib.name}]`;\n\n try {\n if (!space) { throw new Error(`space required. (E: 941f973d50e84415b58724af173f52c2)`); }\n if (!ibGib) { throw new Error('ibGib required.'); }\n\n let ibGibAddr = getIbGibAddr({ ibGib });\n const { gib } = getIbAndGib({ ibGibAddr });\n if (gib === GIB) { return ibGib; }\n let isTjp = await isTjp_Naive({ ibGib, naive });\n if (isTjp) { return ibGib; }\n\n // the given ibGib arg isn't itself the tjp\n\n // if no rel8ns, then there is no tjp ibgib, since this is not\n // intrinsically the tjp and there is no 'tjp' or 'past' rel8n to check\n if (!ibGib.rel8ns) {\n if (logalot) { console.log(`${lc} ibgib not tjp in data, and rel8ns is falsy. so tjp is undefined (I: acdadb76a7568807db7a68f6f866de22)`); }\n return undefined; // <<<< returns early\n }\n\n // check explicitly listed tjp in rel8ns\n if (ibGib.rel8ns!.tjp && ibGib.rel8ns!.tjp.length > 0) {\n let firstTjpAddr = ibGib.rel8ns!.tjp[0];\n let resGetTjpIbGib = await getFromSpace({ addr: firstTjpAddr, space });\n if (resGetTjpIbGib.success && resGetTjpIbGib.ibGibs?.length === 1) {\n return resGetTjpIbGib.ibGibs[0]\n } else {\n const resErrorMsg = resGetTjpIbGib.errorMsg ?? '[unspecified error in get result]';\n throw new Error(`ibGib references tjp but could not retrieve from space. res error: ${resErrorMsg} (E: 94f0340706ad48c794c6a62c1b235a22)`);\n }\n }\n\n // couldn't get the tjp from the rel8ns.tjp, so look for manually in past.\n // but we can't just get the earliest in the 'past', because the tjp\n // may be one of the intermediates!\n // So, check the immediate past ibGib recursively.\n\n const past = ibGib.rel8ns!.past || [];\n if (past.length === 0) {\n console.warn(`${lc} past.length === 0, so there is no tjp.`)\n if (logalot) { console.log(`${lc} ibgib is not tjp in data, not in tjp rel8n, and past is empty. so tjp is undefined (I: bf06f664917dcf4492fb9c4c106a6222)`); }\n return undefined; // <<<< returns early\n }\n const pastIbGibAddr = past[past.length - 1];\n const resGetPastIbGib = await getFromSpace({ addr: pastIbGibAddr, space });\n if (!resGetPastIbGib.success || resGetPastIbGib.ibGibs?.length !== 1) { throw new Error(`get past failed. addr: ${pastIbGibAddr}`); }\n const pastIbGib = resGetPastIbGib.ibGibs![0];\n\n // call this method recursively!\n return await getTjpIbGib({ ibGib: pastIbGib, naive, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n// #region creates\n\n/**\n * Routing function to various `create_____` functions.\n *\n * @returns address of newly created special.\n */\nexport async function createSpecial({\n type,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n type: SpecialIbGibType,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial.name}]`;\n try {\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized. (E: 66e7d3ff098248f0a5ddda51853c92e6)`); }\n\n switch (type) {\n case \"roots\": return createSpecial_Roots({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"tags\": return createSpecial_Tags({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n // case \"latest\": return createSpecial_Latest({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"secrets\": return createSpecial_Secrets({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"encryptions\": return createSpecial_Encryptions({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"outerspaces\": return createSpecial_OuterSpaces({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"autosyncs\": return createSpecial_Autosyncs({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"robbots\": return createSpecial_Robbots({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n case \"apps\": return createSpecial_Apps({ space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n default: return createSpecial_Default({ type, space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Creates a new special ibgib, persists it and if not skipped, relates\n * it to the current root.\n *\n * @returns newly created ibgib (not just address)\n */\nexport async function createSpecialIbGib({\n type,\n skipRel8ToRoot,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n type: SpecialIbGibType,\n skipRel8ToRoot?: boolean,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGib_V1> {\n const lc = `[${createSpecialIbGib.name}][${type || 'falsy type?'}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const specialIb = getSpecialIbGibIb({ type });\n const src = factory.primitive({ ib: specialIb });\n const resNewSpecial = await fork({\n src,\n destIb: specialIb,\n linkedRel8ns: [Rel8n.past, Rel8n.ancestor],\n tjp: { uuid: true, timestamp: true },\n dna: true,\n nCounter: true,\n });\n await persistTransformResult({ resTransform: resNewSpecial, space });\n // we don't relate the special roots index to itself and we don't relate\n // the latest index as it is a super (woohoo!) special ephemeral ibgib.\n if (type !== 'roots' && type !== 'latest' && !skipRel8ToRoot) {\n await rel8ToCurrentRoot({\n ibGib: resNewSpecial.newIbGib,\n linked: true,\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n }\n if (logalot) { console.log(`${lc} complete.`); }\n return resNewSpecial.newIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Creates a new tags^gib instance (unique to current space), as well as\n * default initial tags, e.g. \"home\", \"favorites\", etc., and relates these\n * individual tags to the tags ibGib itself.\n *\n * Stores the tags ibGib's addr in config.\n */\nexport async function createSpecial_Tags({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Tags.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 9c05b9bd355943a39ca47afef67a50eb)`); }\n\n const configKey = getSpecialConfigKey({ type: \"tags\" });\n const special = await createSpecialIbGib({\n type: \"tags\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n let addr = getIbGibAddr({ ibGib: special });\n await setConfigAddr({ key: configKey, addr: addr, space, zeroSpace, fnUpdateBootstrap });\n\n // at this point, our tags ibGib has no associated tag ibGibs.\n // add home, favorite tags\n const initialTagDatas: TagData_V1[] = [\n { text: 'home', icon: 'home-outline' },\n { text: 'favorite', icon: 'heart-outline' },\n ];\n for (const data of initialTagDatas) {\n const resCreate = await createTagIbGibAndSundry({ ...data, space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n addr = resCreate.newTagsAddr;\n await setConfigAddr({ key: configKey, addr: addr, space, zeroSpace, fnUpdateBootstrap });\n }\n\n return addr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\n/**\n * 1. Creates a new tag ibgib with the given properties.\n * 2. Persists graph in given {@link space}\n * 3. Registers the new tag ibgib in that space, using the given\n * {@link fnUpdateBootstrap} and {@link fnBroadcast} functions.\n * 4. Relates the new tag to the special tags ibgib.\n *\n * @returns the new tag ibgib and new tags address.\n */\nexport async function createTagIbGibAndSundry({\n text,\n icon,\n description,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n text: string,\n icon?: string,\n description?: string,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<{ newTagIbGib: TagIbGib_V1, newTagsAddr: string }> {\n const lc = `[${createTagIbGibAndSundry.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!space) { throw new Error(`space required. (E: 5def0b1afab74b0c9286e3ac5060cb8f)`); }\n\n if (!text) { throw new Error(`${lc} text required`); }\n icon = icon || DEFAULT_TAG_ICON;\n description = description || DEFAULT_TAG_DESCRIPTION;\n const tagIb = tagTextToIb(text);\n const tagPrimitive = factory.primitive({ ib: \"tag\" });\n const resNewTag = await factory.firstGen({\n parentIbGib: tagPrimitive,\n ib: tagIb,\n data: { text, icon, description },\n tjp: { uuid: true, timestamp: true },\n dna: true,\n nCounter: true,\n });\n const newTag = resNewTag.newIbGib as TagIbGib_V1;\n await persistTransformResult({ resTransform: resNewTag, space });\n await registerNewIbGib({ ibGib: newTag, space, fnBroadcast, });\n const newTagsAddr = await rel8TagToTagsIbGib({\n tagIbGib: newTag, space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n return { newTagIbGib: newTag, newTagsAddr };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function createSpecial_Roots({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Roots.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: d12a8ea31163429fb6e53ff8e7579c57)`); }\n\n const configKey = getSpecialConfigKey({ type: \"roots\" });\n // const rootsIbGib = await createSpecialIbGib({type: \"roots\", space});\n const rootsIbGib = await createSpecialIbGib({\n type: \"roots\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n let rootsAddr: IbGibAddr | undefined = getIbGibAddr({ ibGib: rootsIbGib });\n await setConfigAddr({ key: configKey, addr: rootsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n // at this point, our ibGib has no associated ibGibs.\n // so we add initial roots\n const rootNames = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];\n\n const initialDatas: RootData[] = rootNames.map(n => {\n return {\n text: `${n}root`,\n icon: DEFAULT_ROOT_ICON,\n description: DEFAULT_ROOT_DESCRIPTION\n };\n });\n let firstRoot: IbGib_V1<RootData> | undefined = undefined;\n for (let i = 0; i < initialDatas.length; i++) {\n const data = initialDatas[i];\n const resCreate = await createRootIbGib({\n ...data,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n if (!firstRoot) { firstRoot = resCreate.newRootIbGib; }\n if (!resCreate.newRootIbGib) { throw new Error(`(UNEXPECTED) resCreate.newRootIbGib falsy? (E: c9fb2c94a9c1d762c1699b41a4d5ad23)`); }\n rootsAddr = resCreate.newRootsAddr;\n // update the config for the updated **roots** ibgib.\n // that roots ibgib is what points to the just created new root.\n await setConfigAddr({ key: configKey, addr: rootsAddr, space, zeroSpace, fnUpdateBootstrap });\n }\n if (!firstRoot) { throw new Error(`(UNEXPECTED) firstRoot still falsy? (E: b2e2c926d242966e7ed7159e4b129e23)`); }\n\n // initialize current root\n await setCurrentRoot({ root: firstRoot, space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n // hack: the above line updates the roots in config. so get **that** addr.\n\n rootsAddr = await getConfigAddr({ key: configKey, space });\n if (!rootsAddr) { throw new Error('(UNEXPECTED) no roots address in config? (E: 76345340699a4738a195e48803ef0d31)'); }\n return rootsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createRootIbGib({\n text,\n icon,\n description,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n text: string,\n icon?: string,\n description?: string,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<{ newRootIbGib: IbGib_V1<RootData>, newRootsAddr: string }> {\n const lc = `[${createRootIbGib.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: cfa876e5c8c64a53a463ca7a645571c8)`); }\n\n text = text || DEFAULT_ROOT_TEXT;\n icon = icon || DEFAULT_ROOT_ICON;\n description = description || DEFAULT_ROOT_DESCRIPTION;\n const ib = getRootIb(text);\n const parentIbGib = factory.primitive({ ib: \"root\" });\n const resNewIbGib = await factory.firstGen({\n parentIbGib,\n ib,\n data: { text, icon, description },\n linkedRel8ns: [Rel8n.past, Rel8n.ancestor],\n tjp: { uuid: true, timestamp: true },\n dna: true,\n nCounter: true,\n });\n const { newIbGib } = resNewIbGib;\n await persistTransformResult({\n resTransform: resNewIbGib,\n space,\n });\n const newRootsAddr = await rel8ToSpecialIbGib({\n type: \"roots\",\n rel8nName: ROOT_REL8N_NAME,\n ibGibsToRel8: [newIbGib],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n return { newRootIbGib: newIbGib as IbGib_V1<RootData>, newRootsAddr };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n// async function createSpecial_Latest({\n// space,\n// zeroSpace,\n// fnUpdateBootstrap,\n// fnBroadcast,\n// }: {\n// space: IbGibSpaceAny,\n// zeroSpace: IbGibSpaceAny,\n// fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n// fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n// }): Promise<IbGibAddr | null> {\n// const lc = `[${createSpecial_Latest.name}]`;\n// try {\n// if (!space) { throw new Error(`space required. (E: 173b08d7eb114238b32280c3efce9d1a)`); }\n\n// const configKey = getSpecialConfigKey({ type: \"latest\" });\n// // const special =\n// // await createSpecialIbGib({type: \"latest\", skipRel8ToRoot: true, space});\n// const special = await createSpecialIbGib({\n// type: \"latest\",\n// space,\n// skipRel8ToRoot: true,\n// zeroSpace,\n// fnBroadcast,\n// fnUpdateBootstrap,\n// });\n// special.gib = GIB;\n// let specialAddr = getIbGibAddr({ ibGib: special });\n// await setConfigAddr({ key: configKey, addr: specialAddr, space, zeroSpace, fnUpdateBootstrap });\n\n// // right now, the latest ibgib doesn't have any more initialization,\n// // since it is supposed to be as ephemeral and non-tracked as possible.\n\n// return specialAddr;\n// } catch (error) {\n// console.error(`${lc} ${error.message}`);\n// return null;\n// }\n// }\n\nasync function createSpecial_Secrets({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Secrets.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 340960cd5ad24addb300b23d9722e30a)`); }\n\n let secretsAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"secrets\" });\n\n // special ibgib doesn't exist, so create it (empty)\n // const secretsIbgib = await createSpecialIbGib({type: \"secrets\", space});\n const secretsIbgib = await createSpecialIbGib({\n type: \"secrets\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n secretsAddr = getIbGibAddr({ ibGib: secretsIbgib });\n await setConfigAddr({ key: configKey, addr: secretsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return secretsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createSpecial_Encryptions({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Encryptions.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 5084e698b6924e7090697ca50075ca59)`); }\n\n let addr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"encryptions\" });\n\n // special ibgib doesn't exist, so create it (empty)\n // const encryptionsIbgib = await createSpecialIbGib({type: \"encryptions\", space});\n const encryptionsIbgib = await createSpecialIbGib({\n type: \"encryptions\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n addr = getIbGibAddr({ ibGib: encryptionsIbgib });\n await setConfigAddr({ key: configKey, addr: addr, space, zeroSpace, fnUpdateBootstrap });\n\n return addr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createSpecial_OuterSpaces({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_OuterSpaces.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: 99dd9e92535c470482eb9f6625a33831)`); }\n\n let outerSpacesAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"outerspaces\" });\n\n // special outerspaces ibgib doesn't exist, so create it (empty)\n // const outerSpacesIbGib = await createSpecialIbGib({type: \"outerspaces\", space});\n const outerSpacesIbGib = await createSpecialIbGib({\n type: \"outerspaces\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n outerSpacesAddr = getIbGibAddr({ ibGib: outerSpacesIbGib });\n await setConfigAddr({ key: configKey, addr: outerSpacesAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return outerSpacesAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nasync function createSpecial_Autosyncs({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Autosyncs.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f01cf6a4a460486796e16d505d629522)`); }\n\n let autosyncsAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"autosyncs\" });\n\n const autosyncsIbGib = await createSpecialIbGib({\n type: \"autosyncs\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n autosyncsAddr = getIbGibAddr({ ibGib: autosyncsIbGib });\n await setConfigAddr({ key: configKey, addr: autosyncsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return autosyncsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nexport async function createSpecial_Robbots({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Robbots.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f01cf6a4a460486796e16d505d629522)`); }\n\n let robbotsAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type: \"robbots\" });\n\n const robbotsIbGib = await createSpecialIbGib({\n type: \"robbots\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n robbotsAddr = getIbGibAddr({ ibGib: robbotsIbGib });\n await setConfigAddr({ key: configKey, addr: robbotsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return robbotsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nexport async function createSpecial_Apps({\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Apps.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: f01cf6a4a460486796e16d505d629522)`); }\n\n let appsAddr: IbGibAddr | undefined | null;\n const configKey = getSpecialConfigKey({ type: \"apps\" });\n\n const appsIbGib = await createSpecialIbGib({\n type: \"apps\",\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n appsAddr = getIbGibAddr({ ibGib: appsIbGib });\n await setConfigAddr({ key: configKey, addr: appsAddr, space, zeroSpace, fnUpdateBootstrap });\n\n // at this point, our apps ibGib has no associated app ibGibs.\n // so create our initial apps.\n // appsAddr = await createApps_Chat({ space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n appsAddr = await createApp({\n defaultAppData: DEFAULT_CHAT_APP_DATA_V1,\n defaultAppRel8ns: DEFAULT_CHAT_APP_REL8NS_V1,\n space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n // appsAddr = await createApps_Raw({ space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n appsAddr = await createApp({\n defaultAppData: DEFAULT_RAW_APP_DATA_V1,\n defaultAppRel8ns: DEFAULT_RAW_APP_REL8NS_V1,\n space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n // appsAddr = await createApps_Todo({ space, zeroSpace, fnUpdateBootstrap, fnBroadcast });\n appsAddr = await createApp({\n defaultAppData: DEFAULT_TODO_APP_DATA_V1,\n defaultAppRel8ns: DEFAULT_TODO_APP_REL8NS_V1,\n space, zeroSpace, fnUpdateBootstrap, fnBroadcast,\n });\n\n return appsAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\nexport async function createApp({\n defaultAppData,\n defaultAppRel8ns,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n /**\n * object that contains all of the default \"data\" for the app. Data here\n * does not mean an app's data like other apps. In ibgib, data is\n * everywhere. This means particularly the defalut app ibGib's data, i.e.\n * `ibGib.data`.\n */\n defaultAppData: any,\n defaultAppRel8ns: any,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createApp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 677f68789abdc7316887e8f38c764e22)`); }\n\n // #region torn from chat-app-v1.ts because of circular dependency...eesh\n\n if (logalot) { console.log(`${lc} starting...`); }\n let data = clone(defaultAppData) as AppData_V1;\n let rel8ns = defaultAppRel8ns ? clone(defaultAppRel8ns) : undefined;\n data.uuid = (!data.uuid || data.uuid === DEFAULT_UUID_TODO_APP) ?\n await getUUID() :\n data.uuid;\n let { classname } = data;\n\n const ib = getAppIb({ appData: data, classname });\n\n const resNewApp = await factory.firstGen({\n ib,\n parentIbGib: factory.primitive({ ib: `app ${classname}` }),\n data: data,\n rel8ns,\n dna: true,\n linkedRel8ns: [Rel8n.ancestor, Rel8n.past],\n nCounter: true,\n tjp: { timestamp: true },\n }) as TransformResult<AppIbGib_V1>;\n\n // #endregion torn from chat-app-v1.ts because of circular dependency...eesh\n\n await persistTransformResult({ resTransform: resNewApp, space });\n await registerNewIbGib({ ibGib: resNewApp.newIbGib, fnBroadcast, space, });\n let appsAddr = await rel8ToSpecialIbGib({\n type: \"apps\",\n rel8nName: APP_REL8N_NAME,\n ibGibsToRel8: [resNewApp.newIbGib],\n fnBroadcast,\n fnUpdateBootstrap,\n space, zeroSpace,\n });\n\n return appsAddr;\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nasync function createSpecial_Default({\n type,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n type: SpecialIbGibType,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr | null> {\n const lc = `[${createSpecial_Default.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: c7bbafcbe901418db4c6048f17f53091)`); }\n\n if (logalot) { console.log(`${lc} creating special of type: ${type} (I: 283c8bb30ed6f9698b74b886c6078622)`); }\n\n let specialAddr: IbGibAddr;\n const configKey = getSpecialConfigKey({ type });\n\n const specialIbGib = await createSpecialIbGib({\n type,\n space,\n zeroSpace,\n fnBroadcast,\n fnUpdateBootstrap,\n });\n specialAddr = getIbGibAddr({ ibGib: specialIbGib });\n await setConfigAddr({ key: configKey, addr: specialAddr, space, zeroSpace, fnUpdateBootstrap });\n\n return specialAddr;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n}\n\n/**\n * 1. Creates a new robbot ibgib with the given properties.\n * 2. Persists graph in given {@link space}\n * 3. Registers the new robbot ibgib in that space, using the given\n * {@link fnUpdateBootstrap} and {@link fnBroadcast} functions.\n * 4. Relates the new robbot to the special robbots ibgib.\n *\n * @returns the new robbot ibgib and new robbots address.\n */\n// export async function createRobbotIbGib({\n// robbotData,\n// space,\n// zeroSpace,\n// fnUpdateBootstrap,\n// fnBroadcast,\n// }: {\n// robbotData: RobbotData_V1,\n// space: IbGibSpaceAny,\n// zeroSpace: IbGibSpaceAny,\n// fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n// fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n// }): Promise<{ newRobbotIbGib: RobbotIbGib_V1, newRobbotsAddr: string }> {\n// const lc = `[${createRobbotIbGib.name}]`;\n// try {\n// if (logalot) { console.log(`${lc} starting...`); }\n// if (!space) { throw new Error(`space required. (E: 5def0b1afab74b0c9286e3ac5060cb8f)`); }\n// if (!robbotData) { throw new Error(`robbotData required (E: cd0304401a2f5a63d86dd71f76f31222)`); }\n\n// const ib = getRobbotIb({ robbotData });\n// const resNewRobbot = await factory.firstGen({\n// parentIbGib: factory.primitive({ ib: \"robbot\" }),\n// ib,\n// data: robbotData,\n// linkedRel8ns: [Rel8n.past, Rel8n.ancestor],\n// tjp: { uuid: true, timestamp: true },\n// dna: true,\n// nCounter: true,\n// });\n// const newRobbot = (resNewRobbot.newIbGib as RobbotIbGib_V1);\n// await persistTransformResult({ resTransform: resNewRobbot, space });\n// await registerNewIbGib({ ibGib: newRobbot, space, zeroSpace, fnBroadcast, fnUpdateBootstrap });\n// const newRobbotsAddr = await rel8ToSpecialIbGib({\n// type: \"robbots\",\n// rel8nName: ROBBOT_REL8N_NAME,\n// ibGibsToRel8: [newRobbot],\n// space,\n// zeroSpace,\n// fnUpdateBootstrap,\n// fnBroadcast,\n// });\n// return { newRobbotIbGib: newRobbot, newRobbotsAddr };\n// } catch (error) {\n// console.error(`${lc} ${error.message}`);\n// throw error;\n// } finally {\n// if (logalot) { console.log(`${lc} complete.`); }\n// }\n// }\n\n\n/**\n * We are NOT searching through all of our data looking for a needle in a haystack.\n * What we ARE doing is we are looking through the past of the existing latest and\n * the prospective latest (the given ibGib param) and comparing between the two.\n *\n * Since `past` rel8n is usually a linked rel8n now, we may have to traverse it all\n * the way to its beginning for each possibility.\n *\n * @returns either {@param ibGibAddr} or {@param existingLatestAddr}\n */\nasync function getLatestAddr_Brute({\n ibGib, ibGibAddr,\n existingLatest, existingLatestAddr,\n tjpAddr,\n space,\n}: {\n ibGib: IbGib_V1<any>, ibGibAddr: string,\n existingLatest: IbGib_V1<any>, existingLatestAddr: string,\n tjpAddr: string,\n space: IbGibSpaceAny,\n}): Promise<string> {\n const lc = `[${getLatestAddr_Brute.name}][${ibGibAddr}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 64eb9a271f5d43deadec30b9638746c8)`); }\n\n // no nCounter, so we need to brute force.\n // The easiest way is to check each's past, as the most common\n // scenario would be registering a newer one, or less likely, a timing issue\n // with registering a previous ibGib frame.\n\n let ibGibPast = ibGib.rel8ns?.past || [];\n let existingLatestPast = existingLatest.rel8ns?.past || [];\n\n // going to check a bunch of specific, easy cases to narrow things down.\n\n if (ibGibPast.length === 1 && existingLatestPast.length === 0) {\n if (logalot) { console.log(`prospective has a past, so it \"must\" be newer. (won't quote \"must\" anymore)`); }\n return ibGibAddr;\n } else if (existingLatestPast.length === 1 && ibGibPast.length === 0) {\n if (logalot) { console.log(`existing has a past, so it must be newer.`); }\n return existingLatestAddr;\n } else if (existingLatestPast.length === 0 && ibGibPast.length === 0) {\n console.warn(`${lc} neither existing latest nor prospective new ibGib has a past, so keeping existing.`);\n return existingLatestAddr;\n } else if (existingLatestPast.includes(ibGibAddr)) {\n if (logalot) { console.log(`existing by definition is newer`); }\n return existingLatestAddr;\n } else if (ibGibPast.includes(existingLatestAddr)) {\n if (logalot) { console.log(`ibGib by definition is newer`); }\n return ibGibAddr;\n } else if (existingLatestAddr === ibGibAddr) {\n if (logalot) { console.log(`they're the same!`); }\n return existingLatestAddr;\n } else if (existingLatestAddr === tjpAddr && existingLatest.rel8ns?.tjp?.length === 1) {\n if (logalot) { console.log(`ibGib must be newer because the existingLatestAddr is the tjp, which is by definition first in unique past.`); }\n return ibGibAddr;\n } else if (ibGibAddr === tjpAddr && ibGib.rel8ns?.tjp?.length === 1) {\n if (logalot) { console.log(`existing must be newer because the ibGibAddr is the tjp, which is by definition first in unique past.`); }\n return existingLatestAddr;\n }\n\n // well, neither one really gives us any indicator alone\n // so load each one in the past\n if (logalot) { console.log(`${lc} brute forcing through iterating the pasts.`); }\n let newerAddr: string | undefined;\n let firstIterationCount = -1; // klugy hack, but is an ugly method anyway (brute after all!)\n\n let getPastCount: (x: IbGib_V1<any>, n: number, otherAddr: string) => Promise<number> =\n async (x, n, otherAddr) => {\n let xPast = x.rel8ns?.past || [];\n if (xPast.includes(otherAddr)) {\n // no need to proceed further, since the other is found in the past of x, so x is newer\n newerAddr = getIbGibAddr({ ibGib: x });\n return -1;\n }\n if (xPast.length === 0) { return n; } // no more past to increment\n let newCount = n + xPast.length;\n if (firstIterationCount !== -1 && newCount > firstIterationCount) {\n // we've determined that the second iteration has a longer past,\n // so we don't need to look further\n newerAddr = getIbGibAddr({ ibGib: x });\n return -1;\n }\n // load up the earliest one and call recursively\n let resNextX = await getFromSpace({ addr: xPast[0], space });\n if (!resNextX.success || resNextX.ibGibs?.length !== 1) { throw new Error(`Couldn't load past addr (xPast[0]): ${xPast[0]}`); }\n return getPastCount(resNextX.ibGibs![0], n + xPast.length, otherAddr);\n }\n\n if (logalot) { console.log(`${lc} doing ibGibPastCount`); }\n let ibGibPastCount = await getPastCount(ibGib, 0, existingLatestAddr);\n if (newerAddr) { return newerAddr; }\n\n // we didn't hit upon it, so set the firstIterationCount so we don't spend unnecessary cycles\n if (logalot) { console.log(`${lc} Doing existingPastCount`); }\n firstIterationCount = ibGibPastCount;\n let existingPastCount = await getPastCount(existingLatest, 0, ibGibAddr);\n if (newerAddr) { return newerAddr; }\n\n // we didn't yet determine it, so whichever has the longer past is newer\n if (ibGibPastCount > existingPastCount) {\n if (logalot) { console.log(`${lc} ibGibPastCount (${ibGibPastCount}) is longer than existingPastCount (${existingPastCount}), so ibGib is newer.`); }\n newerAddr = ibGibAddr;\n } else {\n if (logalot) { console.log(`${lc} existingPastCount (${existingPastCount}) is longer than ibGibPastCount (${ibGibPastCount}), so ibGib is newer.`); }\n newerAddr = existingLatestAddr;\n }\n return newerAddr;\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// #endregion\n\n\n/**\n * Relates the given tag to the TagsIbGib, saves the generated\n * TagsIbGib and updates the settings to point to the new TagsIbGib.\n *\n * @param tagIbGib to add to Tags\n */\nexport function rel8TagToTagsIbGib({\n tagIbGib,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n tagIbGib: IbGib_V1,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<IbGibAddr> {\n return rel8ToSpecialIbGib({\n type: \"tags\",\n rel8nName: TAG_REL8N_NAME,\n ibGibsToRel8: [tagIbGib],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n}\n\n\n/**\n * Throws an error if any duplicates found in either array.\n *\n * ## notes\n *\n * Only pass in ibGib or ibGibAddrs, not both. Warns if both are passed in though.\n *\n * @throws if both params are falsy or if addrs || mapped addrs contains duplicates.\n */\nexport function throwIfDuplicates({\n ibGibs,\n ibGibAddrs,\n}: {\n ibGibs?: IbGib_V1[],\n ibGibAddrs?: IbGibAddr[],\n}): void {\n const lc = `[${throwIfDuplicates.name}]`;\n try {\n if (!ibGibs && !ibGibAddrs) { throw new Error(`either ibGibs or ibGibAddrs required. (E: 37776788620f4966b0964945ce181fc6)`); }\n if (ibGibs && ibGibAddrs) { console.warn(`${lc} both ibGibs and ibGibAddrs provided. You should only provide one. Only ibGibAddrs will be checked. (W: dc13f9e197834e2daaba3bcfd08418db)`); }\n\n const addrs = ibGibAddrs ? ibGibAddrs.concat() : ibGibs!.map(x => getIbGibAddr({ ibGib: x }));\n for (let i = 0; i < addrs.length; i++) {\n const addr = addrs[i];\n if (addrs.filter(x => x === addr).length > 1) { throw new Error(`duplicate addr found: ${addr} (E: 70fbef040dd449c38c667d53b8092053)`); }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function getSpaceLockAddr({\n space,\n scope,\n}: {\n space: IbGibSpaceAny,\n scope: SpaceLockScope,\n}): IbGibAddr {\n const lc = `[${getSpaceLockAddr.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 3ba16e6c3e5e47948b0e63448da11752)`); }\n if (!space.data?.uuid) { throw new Error(`invalid space (space.data.uuid falsy) (E: 273262b32f2ef27b2e690bc699f33822)`); }\n if (!scope) { throw new Error(`scope required. (E: f47801d6c45e2247b42a53d9b604b522)`); }\n while (scope.includes(IBGIB_DELIMITER)) {\n if (logalot) { console.log(`${lc} scope contains ibgib delimiter...replacing... (I: 0f456fd7cc6552a799673a0c5b4a7d22)`); }\n scope = scope.replace(IBGIB_DELIMITER, '_');\n }\n\n const spaceId = space.data!.uuid;\n const ib = `${SPACE_LOCK_IB_TERM} ${spaceId} ${scope}`;\n const gib = GIB;\n return getIbGibAddr({ ib, gib });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Executes some function `fn` against/in a given `space` while\n * performing lock plumbing in that space.\n *\n * By this, I mean that this function takes care of acquiring the lock,\n * attempting retries according to the parameters, and then unlocking\n * the space regardless of result/error.\n *\n * @returns result of inner `fn` with `TResult`\n */\nexport async function execInSpaceWithLocking<TResult>({\n space,\n scope,\n secondsValid,\n maxDelayMs,\n fn,\n callerInstanceId,\n maxLockAttempts,\n}: {\n space: IbGibSpaceAny,\n scope: string,\n secondsValid: number,\n /**\n * If resource locked, will delay at max this ms.\n */\n maxDelayMs?: number,\n fn: () => Promise<TResult>,\n /**\n * for use differentiating among tabs.\n *\n * ## intent\n * the idea is the ibgibs service has an instance id and passes it in here.\n */\n callerInstanceId?: string,\n /**\n * if given, will try to acquire lock at most this many times, else\n * will default to {@link DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS}.\n */\n maxLockAttempts?: number,\n}): Promise<TResult> {\n const lc = `[${execInSpaceWithLocking.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // #region validation\n\n if (!space) { throw new Error(`space required. (E: 66fd8f21a5b2b572d18cdeb9472a7722)`); }\n if (!secondsValid) { throw new Error(`secondsValid required. (E: 92c5610e57ceede5ce83cff86d5c2a22)`); }\n if (secondsValid < 0) { throw new Error(`secondsValid must be positive. (E: 970a7510c517235d7a355a843d18d222)`); }\n // if (secondsValid > MAX_LOCK_SECONDS_VALID) { throw new Error(`secondsValid arg (${secondsValid}) exceeds max secondsValid (${MAX_LOCK_SECONDS_VALID}) (E: 4cffe49a23c8f1698bf7c78eaccbb722)`); }\n if (!fn) { throw new Error(`fn required (E: 7022e280252ec2faf756b6db05c56e22)`); }\n\n // #endregion validation\n\n let resultFn: TResult;\n\n if (logalot) { console.log(`${lc} attempting to acquire lock with scope ${scope} (I: fed36d42a975b1c52897a4df804ac722)`); }\n let lockIbGib: IbGibSpaceLockIbGib;\n maxDelayMs =\n (maxDelayMs ?? 0) > 0 ? maxDelayMs : DEFAULT_MAX_DELAY_MS_RETRY_LOCK_ACQUIRE\n let attempts = 0;\n maxLockAttempts =\n maxLockAttempts ?? -1 > 0 ?\n maxLockAttempts :\n DEFAULT_MAX_DELAY_RETRY_LOCK_ACQUIRE_ATTEMPTS;\n do {\n lockIbGib = await lockSpace({\n space,\n scope,\n secondsValid,\n instanceId: callerInstanceId,\n });\n if (lockIbGib?.data?.success) { break; }\n /** Delay a small random amount of time before trying again. */\n let delayMs = Math.ceil(Math.random() * maxDelayMs!);\n await delay(delayMs);\n attempts++;\n } while (attempts < maxLockAttempts!);\n if (lockIbGib?.data?.success) {\n if (logalot) { console.log(`${lc} lock acquired. (I: d847fa953ee131a57e1a89c537342722)`); }\n } else {\n throw new Error(`could not acquire lock after ${attempts} attempts with intermittent delays of ${maxDelayMs} ms (E: 898c559dbd0c9bf20c14cf87a8f1e222)`);\n }\n\n // execute the actual get inside an additional try..catch..finally\n // to ensure (attempted) unlockSpace call.\n const lc2 = `${lc}[fn]`;\n try {\n if (logalot) { console.log(`${lc2} starting... (I: c2f7bedf95d3f1dd1f76de34a68d3f22)`); }\n resultFn = await fn();\n } catch (error) {\n console.error(`${lc2} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc2} unlocking space with scope: ${scope} (I: 21034d9c3395499756e9000e40417d22)`); }\n await unlockSpace({ space: space, scope: scope, instanceId: callerInstanceId });\n if (logalot) { console.log(`${lc2} complete. (I: 79d8ac03714a4d429c7e6c2ac6e18d22)`); }\n }\n\n return resultFn;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Gets the bootstrap ibgib in the given `zeroSpace`.\n *\n * @example\n *\n * ```json\n * {\n * \"ib\":\"bootstrap\",\n * \"gib\":\"gib\",\n * \"data\":{\n * \"defaultSpaceId\":\"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\",\n * \"spaceIds\":[\"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\"]\n * },\n * \"rel8ns\":{\n * \"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\":[\n * \"witness space IonicSpace_V1 oij d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33^B336251655E8C56B38E9E86F20E0E42E6C153785F1A0A798ADE6916E71CF055B\"\n * ]\n * }\n * }\n * ```\n *\n * @returns bootstrapIbGib if found, else null\n */\nexport async function getValidatedBootstrapIbGib({\n zeroSpace,\n}: {\n zeroSpace: IbGibSpaceAny,\n}): Promise<BootstrapIbGib | null> {\n const lc = `[${getValidatedBootstrapIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: 66fd8f21a5b2b572d18cdeb9472a7722)`); }\n\n const bootstrapAddr = BOOTSTRAP_IBGIB_ADDR;\n\n if (logalot) { console.log(`${lc} getting from zeroSpace...`); }\n const argGet = await zeroSpace.argy({\n ibMetadata: getSpaceArgMetadata({ space: zeroSpace }),\n argData: {\n cmd: 'get',\n ibGibAddrs: [bootstrapAddr],\n },\n });\n const resGetBootstrapIbGib = await zeroSpace.witness(argGet);\n\n if (resGetBootstrapIbGib?.data?.success && resGetBootstrapIbGib.ibGibs?.length === 1) {\n // bootstrap found\n const bootstrapIbGib = resGetBootstrapIbGib!.ibGibs![0]!;\n if (logalot) { console.log(`${lc} bootstrapibGib found: ${pretty(bootstrapIbGib)}`); }\n if (await validateBootstrapIbGib(bootstrapIbGib)) {\n return (bootstrapIbGib as BootstrapIbGib);\n } else {\n if (logalot) { console.log(`${lc} bootstrapIbGib was invalid. (I: cce66b26805404fc85525d565e1f8b22)`); }\n return null;\n }\n } else {\n // bootstrap NOT found\n if (logalot) { console.log(`${lc} bootstrapIbGib NOT found. (I: 421562993bf3464eb507d2967d311e22)`); }\n return null;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * So when loading the local user space, even if the class changes or default\n * constructors change, the internal `data` is loaded from file.\n */\nexport async function getLocalSpace<TSpace extends IbGibSpaceAny>({\n zeroSpace,\n bootstrapIbGib,\n localSpaceId,\n lock,\n callerInstanceId,\n fnDtoToSpace,\n localSpaceCacheSvc,\n}: {\n /**\n * A zero space is a space that is built with default settings that\n * is not specific to a user.\n *\n * This is the foundational space that all spaces share, out of which\n * a bootstrap ibgib can be found that will itself have rel8ns to other\n * spaces.\n *\n * ## notes\n *\n * This is what I was calling a zeroSpace, but that will in the future\n * mean a default space among a group of spaces.\n */\n zeroSpace: IbGibSpaceAny,\n /**\n * bootstrap ibGib, if provided, which was found in the zero space.\n * The bootstrap ibgib should have a rel8n entry to the local space.\n *\n * ## future\n *\n * We will have multiple local spaces to choose from, with a default\n * being the one that we're referring to atow.\n */\n bootstrapIbGib?: BootstrapIbGib,\n /**\n * If provided, will look for the space via this id in the bootstrap ibgib.\n * If not provided, will use the bootstrap ibgib's default spaceId.\n */\n localSpaceId?: SpaceId,\n /**\n * If true, we will lock on getting the bootstrap ibgib (if needed), as\n * well as getting the user space.\n */\n lock?: boolean,\n /**\n * for use differentiating among tabs.\n *\n * ## intent\n * the idea is the ibgibs service has an instance id and passes it in here.\n */\n callerInstanceId: string,\n /**\n * function that turns the space dto into the space witness.\n *\n * ## intent\n *\n * When loading a space, the only part stored is the ibgib data. You still\n * need a function that hydrates a witness class with that data.\n */\n fnDtoToSpace: (spaceDto: IbGib_V1) => Promise<TSpace>,\n /**\n * Optional caching service\n */\n localSpaceCacheSvc?: IbGibCacheService,\n}): Promise<TSpace> {\n const lc = `[${getLocalSpace.name}]`;\n try {\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: 0793781a98c456a666cfa9eb960bcd22)`); }\n\n if (!bootstrapIbGib) {\n if (logalot) { console.log(`${lc} bootstrap falsy, so loading it... (I: f2366e38283495a38b5501297aa34422)`); }\n if (lock) {\n const bootstrapAddr = BOOTSTRAP_IBGIB_ADDR;\n if (logalot) { console.log(`${lc} using locked version of loading bootstrap... (I: 52b9b11999674e586d051c2b23f59b22)`); }\n bootstrapIbGib = await execInSpaceWithLocking<BootstrapIbGib>({\n space: zeroSpace,\n scope: bootstrapAddr,\n fn: async () => {\n let validatedBootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace });\n if (validatedBootstrapIbGib) {\n return validatedBootstrapIbGib;\n } else {\n throw new Error(`(UNEXPECTED) unable to get bootstrap ibgib? (E: c111dc7627acbfb992134ddf4064ea23)`);\n }\n },\n callerInstanceId,\n secondsValid: DEFAULT_SECONDS_VALID_LOCAL,\n });\n } else {\n if (logalot) { console.log(`${lc} lock is false, so just getting the bootstrap ibgib (I: 49d55e5a824510bb3ee0ccd9f5ec3322)`); }\n bootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace }) ?? undefined;\n }\n }\n\n if (!bootstrapIbGib) { throw new Error(`bootstrapIbGib falsy. not initialized? (E: 91f5c82b5e124178d958701ebcb09822)`); }\n\n if (!bootstrapIbGib.data) { throw new Error(`(UNEXPECTED) bootstrapIbGib.data required. invalid bootstrap? (E: 568c6b837c1a39f7a25d188a90167423)`); }\n\n localSpaceId = localSpaceId ?? bootstrapIbGib!.data[BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY];\n const localSpaceAddr = bootstrapIbGib.rel8ns![localSpaceId]![0]; // guaranteed b/c bootstrap was validated\n\n const fnGet: () => Promise<TSpace> = async () => {\n\n const argGet = await zeroSpace.argy({\n ibMetadata: getSpaceArgMetadata({ space: zeroSpace }),\n argData: {\n cmd: 'get',\n ibGibAddrs: [localSpaceAddr],\n },\n });\n const resLocalSpace = await zeroSpace.witness(argGet);\n if (resLocalSpace?.data?.success && resLocalSpace.ibGibs?.length === 1) {\n const localSpaceDto = resLocalSpace.ibGibs[0] as TSpace;\n const localSpace = await fnDtoToSpace(localSpaceDto);\n if (localSpaceCacheSvc) { localSpace.cacheSvc = localSpaceCacheSvc; }\n return localSpace;\n } else {\n throw new Error(`Could not get local space addr (${localSpaceAddr}) specified in bootstrap space (${getIbGibAddr({ ibGib: bootstrapIbGib })}). (E: 6d6b45e7eae4472697ddc971438e4922)`);\n }\n }\n\n if (lock) {\n if (logalot) { console.log(`${lc} getting localSpaceId (${localSpaceId}) WITH locking (I: c48a0e4ac5971cdbc57273dd35f8a522)`); }\n return await execInSpaceWithLocking({\n space: zeroSpace,\n scope: localSpaceId,\n fn: () => { return fnGet(); },\n callerInstanceId,\n secondsValid: DEFAULT_SECONDS_VALID_LOCAL,\n });\n } else {\n if (logalot) { console.log(`${lc} getting localSpaceId (${localSpaceId}) WITHOUT locking (I: 48e504835dee4006839df8820d860b22)`); }\n return fnGet();\n }\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport async function lockSpace({\n space,\n scope,\n secondsValid,\n instanceId,\n}: IbGibSpaceLockOptions): Promise<IbGibSpaceLockIbGib> {\n const lc = `[${lockSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 5c0a7197a75f483a82d74e5eea60df37)`); }\n if (!scope) { throw new Error(`scope required. (E: c7f1dde9570f4df3b450faa2c2f85122)`); }\n if (!secondsValid) { throw new Error(`secondsValid required and positive (E: b42b6733638b46c06c9aff59a6c49822)`); }\n if (secondsValid < 0) { throw new Error(`secondsValid must be positive (E: bbe3b6d567583bfb35a1c0825eb29622)`); }\n\n /** what we will return */\n let resLockIbGib: IbGibSpaceLockIbGib;\n\n /** space lock address is deterministic ibgib primitive (gib === 'gib') */\n const spaceLockAddr = getSpaceLockAddr({ space, scope });\n\n // check for existing lock...\n let existingLock: IbGibSpaceLockIbGib | undefined;\n\n // ...in space's backing store (file, IndexedDB entry, DB, etc.)\n\n let getLock = await getFromSpace({\n addr: spaceLockAddr, space, force: true\n });\n if (getLock.success && getLock.ibGibs?.length === 1) {\n existingLock = getLock.ibGibs[0] as IbGibSpaceLockIbGib;\n if (existingLock?.data?.expirationUTC) {\n if (isExpired({ expirationTimestampUTC: existingLock.data.expirationUTC })) {\n // lock expired, so log only. skipping delete atow because should be overwritten\n // when the new lock is in place.\n console.warn(`${lc} ignoring expired existing lock in space at ${spaceLockAddr}. Should be overwritten (W: 7421c5b051724b189f88cecbbd449b22)`);\n existingLock = undefined;\n }\n } else {\n console.error(`${lc} (UNEXPECTED) exisingLock.data.expirationUTC falsy? (E: 218dc0e935534a149d0be153c532cf25)`);\n existingLock = undefined;\n }\n } else {\n if (logalot) { console.log(`${lc} existing lock not found for ${spaceLockAddr} (I: 191af56ec4e2db3d19084e46bf949222)`); }\n }\n\n // populate resLockIbGib if/else existingLock\n if (existingLock) {\n if (!existingLock.data) { throw new Error(`(UNEXPECTED) existingLock.data falsy? (E: 00069b4662e5566d971760d15e293723)`); }\n // valid lock already exists, so return informing caller. this\n // includes the existing lock's info, i.e. its expiration\n resLockIbGib = clone(existingLock) as IbGibSpaceLockIbGib;\n resLockIbGib.data!.alreadyLocked = true;\n resLockIbGib.data!.success = false;\n } else {\n // not yet locked so immediately lock in memory for space, then via\n // `space.put(lock)`\n const { ib, gib } = getIbAndGib({ ibGibAddr: spaceLockAddr });\n resLockIbGib = {\n ib, gib,\n data: {\n scope,\n secondsValid,\n instanceId,\n expirationUTC: getExpirationUTCString({ seconds: secondsValid }),\n }\n } as IbGibSpaceLockIbGib;\n\n // We must use space.witness (via argy) directly here instead of\n // `putInSpace` helper, because we need to check\n // `addrsAlreadyHave`. If the space already has the addr, then\n // we have lost a race condition and the space is ALREADY locked.\n const argPut = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'put',\n force: true,\n ibGibAddrs: [spaceLockAddr],\n },\n ibGibs: [resLockIbGib],\n });\n const resPut = await space.witness(argPut);\n\n if (resPut.data?.success) {\n if ((resPut.data.addrsAlreadyHave ?? []).includes(spaceLockAddr)) {\n // Race condition lost! The lock was put by someone else in the interim.\n if (logalot) { console.log(`${lc} racelost! addrsAlreadyHave includes spaceLockAddr (${spaceLockAddr}) (I: 2e8a1562947c40698110b64251141753)`); }\n\n // get the existing lock that beat us\n const getLockRace = await getFromSpace({\n addr: spaceLockAddr, space, force: true\n });\n if (getLockRace.success && getLockRace.ibGibs?.length === 1) {\n const existingLockRace = getLockRace.ibGibs[0] as IbGibSpaceLockIbGib;\n resLockIbGib = clone(existingLockRace) as IbGibSpaceLockIbGib;\n resLockIbGib.data!.alreadyLocked = true;\n resLockIbGib.data!.success = false;\n } else {\n // Should be unreachable if addrsAlreadyHave is true, but handle gracefully\n const emsg = `${lc} (UNEXPECTED) addrsAlreadyHave true, but couldn't get lock? (E: 8374a2b6628b49369363bc5843105763)`;\n console.error(emsg);\n resLockIbGib.data!.success = false;\n resLockIbGib.data!.errorMsg = emsg;\n }\n } else {\n // Success! We put the lock and it was new.\n resLockIbGib.data!.success = true;\n }\n } else {\n const emsg = `${lc} there was an error putting the lock in the space: ${resPut.data?.errors?.join('|')}`;\n resLockIbGib.data!.success = false;\n resLockIbGib.data!.errorMsg = emsg;\n console.error(emsg);\n }\n }\n\n return resLockIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function unlockSpace({\n space,\n scope,\n instanceId,\n}: IbGibSpaceLockOptions): Promise<IbGibSpaceLockIbGib | undefined> {\n const lc = `[${unlockSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 5c0a7197a75f483a82d74e5eea60df37)`); }\n if (!scope) { throw new Error(`scope required. (E: c7f1dde9570f4df3b450faa2c2f85122)`); }\n\n /** space lock address is deterministic ibgib primitive (gib === 'gib') */\n const spaceLockAddr = getSpaceLockAddr({ space, scope });\n\n // delete in file if it exists\n let resDelete = await deleteFromSpace({ addr: spaceLockAddr, space, force: true });\n if (resDelete.success) {\n const { ib, gib } = getIbAndGib({ ibGibAddr: spaceLockAddr });\n return {\n ib, gib,\n data: {\n // action: 'unlock',\n success: true,\n instanceId,\n scope,\n }\n } as IbGibSpaceLockIbGib;\n } else {\n /** May NOT be an error, just setting this here is convenient to code. */\n const emsg = `Delete lock in space failed. delete errorMsg: ${resDelete.errorMsg}`;\n if (emsg.includes('not implemented')) {\n // rethrow error if space has not implemented a delete command handler\n throw new Error(emsg);\n } else if (\n emsg.toLowerCase().includes(`does not exist`) ||\n emsg.toLowerCase().includes(`doesn't exist`) ||\n emsg.toLowerCase().includes(`not found`)\n ) {\n // don't want to warn if just file didn't exist\n if (logalot) { console.log(`${lc} ${emsg} (I: b647916fd0f3e5366e9387131be21c22)`); }\n const { ib, gib } = getIbAndGib({ ibGibAddr: spaceLockAddr });\n return {\n ib, gib,\n data: {\n action: 'unlock',\n success: true,\n instanceId,\n scope,\n }\n } as IbGibSpaceLockIbGib;\n } else {\n console.warn(`${lc} ${emsg} (W: 14c84fcac15944bd9a417099964d5d9d)`);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Updates the bootstrap^gib record in the default space data store\n * with the 'space' rel8n set to the `newSpaceAddr`.\n *\n * This way, if the app closes at this point, it will know to look at this\n * space when it loads.\n *\n * ## notes\n *\n * I'm probably typing this all over, but the bootstrap^gib is the\n * first record that the app looks at to know what space to load.\n * The space itself has configuration and has a proper gib hash\n * so it's verifiable. But the initial bootstrap^gib record is\n * NOT, since it only has 'gib' as its address (and thus its not hashed).\n *\n * In the future, this could be alleviated by asking other witnesses\n * \"Hey what was my last bootstrap^gib hash\", but there's no way to\n * do it beyond this without using some kind of authentication/secret(s)\n * that generate the record, i.e. encrypting bootstrap^gib cleverly.\n */\nexport async function updateBootstrapIbGib({\n space,\n zeroSpace,\n setSpaceAsDefault,\n createIfNotFound,\n}: {\n /**\n * space to add/replace in the bootstrap^gib ibgib.\n */\n space: IbGibSpaceAny,\n /**\n * default \"zero\" space which contains a bootstrap^gib ibgib.\n */\n zeroSpace?: IbGibSpaceAny,\n /**\n * set the space as the default local space in the bootstrap^gib ibgib.\n */\n setSpaceAsDefault?: boolean,\n /**\n * If bootstrap not found, create a new one\n */\n createIfNotFound?: boolean,\n}): Promise<void> {\n const lc = `[${updateBootstrapIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 6fc19548fa7d1d5219e19871f280a322)`); }\n if (!space.data?.uuid) { throw new Error(`space.data.uuid required (E: 6483188ca6f2ed2085fd355595f3ab22)`); }\n if (!zeroSpace) { throw new Error(`zeroSpace required. (E: abbf156e18b1018d96273e22a260f122)`); }\n\n const spaceId = space.data.uuid;\n const newSpaceAddr = getIbGibAddr({ ibGib: space });\n\n /** validated bootstrap ibgib or null */\n let bootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace });\n if (!bootstrapIbGib) {\n if (!createIfNotFound) {\n if (logalot) { console.log(`${lc} bootstrapIbGib not found but createIfNotFound falsy, so returning early. (I: 5c67d85a8599a5ba4a6780f26a66ea22)`); }\n return; /* <<<< returns early */\n }\n\n // create the bootstrap^gib space that points to user space\n if (logalot) { console.log(`${lc} creating new bootstrap ibgib for spaceId (${spaceId}) with address of (${newSpaceAddr}) (I: 651959c27bf2ebc5be1f7f44e2b9e422)`); }\n const { ib: bootstrapIb, gib } = getIbAndGib({ ibGibAddr: BOOTSTRAP_IBGIB_ADDR });\n bootstrapIbGib = (factory.primitive as any)({ ib: bootstrapIb });\n bootstrapIbGib!.gib = gib;\n bootstrapIbGib!.data = {\n /**\n * first space is automatically set as default, regardless of\n * `setSpaceAsDefault` value\n */\n [BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY]: spaceId,\n [BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY]: [spaceId],\n } as BootstrapData;\n bootstrapIbGib!.rel8ns = {\n /**\n * individual spaces indexed by spaceId, should be length === 1\n * with the value being the most recent.\n */\n [spaceId]: [newSpaceAddr],\n } as BootstrapRel8ns;\n } else {\n // at this point, we have a validated bootstrap.\n // update existing bootstrap with newSpaceAddr for given spaceId\n if (logalot) { console.log(`${lc} updating existing bootstrap (I: 977d4aa7ed47bef73b35743c05ce0722)`); }\n if (bootstrapIbGib.data!.spaceIds.includes(spaceId)) {\n if (logalot) { console.log(`${lc} space already rel8d to bootstrap, possibly updating its addr (I: b5e2c515ef732d4bbcf02625a9e7c722)`); }\n const existingSpaceAddr = bootstrapIbGib.rel8ns![spaceId]![0];\n if (existingSpaceAddr === newSpaceAddr) {\n if (logalot) { console.log(`${lc} bootstrap already rel8d to space (I: c1be027b23e7350c64790a631cae2822)`); }\n } else {\n if (logalot) { console.log(`${lc} updating rel8ns[${spaceId}] with newSpaceAddr (${newSpaceAddr}). (Old address: ${existingSpaceAddr})(I: 297a9b0061fd471b8d28a06e04a6ad22)`); }\n bootstrapIbGib.rel8ns![spaceId] = [newSpaceAddr];\n }\n } else {\n // new space being rel8d to bootstrap\n if (logalot) { console.log(`${lc} new space being rel8d. adding spaceId to data.spaceIds and amending rel8ns (I: 40903d71719aa1d56e498299f5699a22)`); }\n bootstrapIbGib.data!.spaceIds.push(spaceId);\n bootstrapIbGib.rel8ns![spaceId] = [newSpaceAddr];\n }\n if (setSpaceAsDefault) {\n if (logalot) { console.log(`${lc} setting spaceId (${spaceId}) as default space (I: f85eda6c6ad2b0bec9750ce3c7795b22)`); }\n bootstrapIbGib.data![BOOTSTRAP_DATA_DEFAULT_SPACE_ID_KEY] = spaceId;\n }\n }\n\n if (!bootstrapIbGib) { throw new Error(`(UNEXPECTED) bootstrapIbGib still falsy? (E: cf21d7f1756710a66aa0e6a28d762723)`); }\n\n if (logalot) { console.log(`${lc} saving bootstrapIbGib: ${pretty(bootstrapIbGib)} (I: 3cceca0b98dde90e4a58a734be252322)`); }\n\n // save the bootstrap^gib in the zero space for future space loadings,\n // especially when the app first starts up\n const argPutBootstrap = await zeroSpace.argy({\n ibMetadata: bootstrapIbGib!.ib,\n argData: {\n cmd: 'put', force: true,\n ibGibAddrs: [getIbGibAddr({ ibGib: bootstrapIbGib })],\n },\n ibGibs: [bootstrapIbGib],\n });\n if (logalot) { console.log(`${lc} zeroSpace will witness/put... (I: 1be9aca22ffc4951b6690965a7aeae5b)`); }\n const resPutBootstrap = await zeroSpace.witness(argPutBootstrap);\n if (resPutBootstrap?.data?.success) {\n if (logalot) { console.log(`${lc} zero space put complete. (I: ac3056d655e841f1a3c442bcc64942f9)`); }\n } else {\n throw new Error(`${resPutBootstrap?.data?.errors?.join('|') || \"There was a problem with zeroSpace witnessing the bootstrap^gib primitive pointing to the new user space\"}`);\n }\n if (logalot) { console.log(`${lc} complete.`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n\n}\n\nexport function getSpaceArgMetadata({ space }: { space: IbGibSpaceAny }): string {\n return `${space.ib} ${getTimestampInTicks()}`;\n}\n\nexport function getSpaceResultMetadata({ space }: { space: IbGibSpaceAny }): string {\n return `${space.ib} ${getTimestampInTicks()}`;\n}\n\n/**\n * builds the space's ib based on either spaceData or space.data, depending on\n * what is passed in. if for some reason both are passed in, this does some\n * basic checking to be sure that they are the same data.\n * @returns generated spaceIb\n */\nexport function getSpaceIb({\n space,\n spaceData,\n classname,\n}: {\n space?: IbGibSpaceAny,\n spaceData?: IbGibSpaceData,\n classname?: string,\n}): Ib {\n const lc = `[${getSpaceIb.name}]`;\n try {\n if (!space && !spaceData) { throw new Error(`either space or spaceData required (E: 4dabec34ee77d67c9cc30ee3c3049622)`); }\n if (space && !space.data) { throw new Error(`(UNEXPECTED) given space has falsy space.data? (E: 058d298876ebbeada7bbddb9e3da2f23)`); }\n if (space && spaceData) {\n if (space.data!.uuid !== spaceData.uuid) { throw new Error(`(UNEXPECTED) both space and spaceData given, but uuid don't match? (E: efdd4603cba93a17340a76811fe56b24)`); }\n if (space.data!.n !== spaceData.n) { throw new Error(`(UNEXPECTED) both space and spaceData given, but n don't match? (E: e51278a707c9bccc57a08a4b86524524)`); }\n }\n spaceData ??= space!.data!;\n if (!spaceData) { throw new Error(`(UNEXPECTED) spaceData falsy? (thought this was a compiler problem that this was even possible.) (E: b3c7ffedcae4b1f45b263b3825930b24)`); }\n\n\n if (classname && spaceData.classname && classname !== spaceData.classname) {\n throw new Error(`both classname arg (${classname}) and spaceData.classname (${spaceData.classname}) are different truthy values. (E: f98f012ee876eb8fbe7403f7b53e4624)`);\n } else {\n classname ||= spaceData.classname;\n }\n if (!classname) { throw new Error(`classname required (E: fa3af4613ad56742dab51d1b0d839322)`); }\n if (classname.includes(' ')) { throw new Error(`invalid classname (${classname}). cannot contain spaces (E: 243adbf720dcce7904e2665933208b22)`); }\n\n const name = spaceData?.name || IBGIB_SPACE_NAME_DEFAULT;\n if (name.includes(' ')) { throw new Error(`invalid space name. cannot contain spaces (E: a8450e1651081412c8ac018520182422)`); }\n\n const id = spaceData?.uuid || undefined;\n if (!id) { throw new Error(`invalid space, spaceData.uuid falsy (E: 50ae723a9ab24f4fc7132613e65faf23)`); }\n if (id.includes(' ')) { throw new Error(`invalid space id. cannot contain spaces (E: 8696830fe7f54bfa85e670a063f3e089)`); }\n\n const spaceType = spaceData.type ?? undefined;\n const spaceSubtype = spaceData.subtype ?? undefined;\n if (spaceType && !spaceSubtype) {\n throw new Error(`spaceType (${spaceType}) is set but spaceSubtype is falsy. (E: 878ab960d7987ae2331103b4a00d0d24)`);\n }\n\n return `${WITNESS_ATOM} ${SPACE_ATOM} ${classname} ${name} ${id} ${spaceType} ${spaceSubtype}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * determines if the given ib belongs to a space ibgib.\n *\n * atow (03/2024) checks to see if the ib starts with\n *\n * `${WITNESS_ATOM} ${SPACE_ATOM} `\n */\nexport function isSpaceIb({\n ib\n}: {\n ib: Ib\n}): boolean {\n const lc = `[${isSpaceIb.name}]`;\n if (!ib) {\n const emsg = `${lc} ib required (E: dd5244f62f964359a86e59bb08ee47e6)`;\n console.error(emsg);\n throw new Error(emsg);\n }\n return ib.startsWith(`${WITNESS_ATOM} ${SPACE_ATOM} `);\n // return ib.startsWith('witness space ') || ib.startsWith('outerspace sync ');\n}\n\n/**\n * atow (03/2024), (space-delimited) schema is...\n *\n * `${WITNESS_ATOM} ${SPACE_ATOM} ${classname} ${name} ${id} ${spaceType} ${spaceSubtype}`\n */\nexport function parseSpaceIb({\n spaceIb,\n}: {\n spaceIb: Ib,\n}): {\n /**\n * currently this can be the classname OR undefined of the space.\n */\n spaceClassname: string | undefined,\n /**\n * non-unique spaceName of the given space (i.e. most likely space.data.name)\n */\n spaceName: string,\n /**\n * currently this returns EITHER SpaceId OR undefined.\n *\n * This is because of my using different schemas for local/outer spaces...\n *\n * (for better or worse)\n */\n spaceId: SpaceId | undefined,\n /**\n * if undefined, by convention, this is a user space\n */\n spaceType: SpaceType | undefined,\n /**\n * subtype, if applicable\n */\n spaceSubtype: SpaceSubtype | undefined,\n} {\n const lc = `[${parseSpaceIb.name}]`;\n try {\n if (!spaceIb) { throw new Error(`spaceIb required (E: fa5424cfb7e846e2851562f2f417944f)`); }\n\n // `${WITNESS_ATOM} ${SPACE_ATOM} ${classname} ${name} ${id} ${spaceType} ${spaceSubtype}`\n const [witnessAtom, spaceAtom, spaceClassname, spaceName, spaceId, spaceType_string, spaceSubtype_string] =\n spaceIb.split(' ');\n\n if (witnessAtom !== WITNESS_ATOM) { throw new Error(`invalid spaceIb (${spaceIb}). witnessAtom !== WITNESS_ATOM (E: 5ae1ca12cf8f30ae341f3e582b025224)`); }\n if (spaceAtom !== SPACE_ATOM) { throw new Error(`invalid spaceIb (${spaceIb}). spaceAtom !== SPACE_ATOM (E: 9cc6b6f30e13455eb29748148a94fa0f)`); }\n if (!spaceClassname) { throw new Error(`invalid spaceIb (${spaceIb}). spaceClassname falsy (E: 00d3392da007ca8b2840b16b199d9a24)`); }\n if (!spaceName) { throw new Error(`invalid spaceIb (${spaceIb}). spaceName falsy (E: b957d8e74ef34d889fa64c60c7a5ea0b)`); }\n if (!spaceId) { throw new Error(`invalid spaceIb (${spaceIb}). spaceId falsy (E: 7a1773722d8e46a0866d683130b65b89)`); }\n\n let spaceType: SpaceType | undefined = undefined;\n if (spaceType_string && spaceType_string !== 'undefined') {\n if (VALID_SPACE_TYPES.includes(spaceType_string as SpaceType)) {\n spaceType = spaceType_string as SpaceType;\n } else {\n throw new Error(`invalid spaceIb (${spaceIb}). spaceType (${spaceType_string}) is set but not a valid type. valid types: ${VALID_SPACE_TYPES.join(', ')} (E: 838f4638a88cfbf3545a3a3a38b6dd24)`);\n }\n }\n\n let spaceSubtype: SpaceSubtype | undefined = undefined;\n if (spaceSubtype_string && spaceSubtype_string !== 'undefined') {\n if (VALID_SPACE_SUBTYPES.includes(spaceSubtype_string as SpaceSubtype)) {\n spaceSubtype = spaceSubtype_string as SpaceSubtype;\n } else {\n throw new Error(`invalid spaceIb (${spaceIb}). spaceSubtype (${spaceSubtype_string}) is set but not a valid subtype. valid subtypes: ${VALID_SPACE_SUBTYPES.join(', ')} (E: 5bdcf23027f94e73860e4340313b04ab)`);\n }\n }\n\n return {\n spaceClassname,\n spaceName,\n spaceId,\n spaceType,\n spaceSubtype,\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * @deprecated\n * use `parseSpaceIb`\n */\nexport function getInfoFromSpaceIb({\n spaceIb,\n}: {\n spaceIb: Ib,\n}): {\n /**\n * currently this can be SpaceId OR undefined.\n */\n spaceClassname: string | undefined,\n /**\n * non-unique spaceName of the given space (i.e. most likely space.data.name)\n */\n spaceName: string,\n /**\n * currently this returns EITHER SpaceId OR undefined.\n *\n * This is because of my using different schemas for local/outer spaces...\n *\n * (for better or worse)\n */\n spaceId: SpaceId | undefined,\n} {\n return parseSpaceIb({ spaceIb });\n}\n\n/**\n * Helper function that generates a unique-ish id.\n *\n * atow this is just `return (await getUUID()).slice(0, DEFAULT_TX_ID_LENGTH);`\n *\n * ## notes\n *\n * The thinking is that it only has to be a couple characters in length\n * because this is supposed to only be a unique id within the scope of\n * a tx which has its own tjp (gib) used as the id for the entire communication\n * saga.\n *\n * @returns txId\n */\nexport async function getNewTxId({\n length,\n}: {\n /**\n * length of txId\n *\n * @default DEFAULT_TX_ID_LENGTH\n */\n length?: number,\n} = { length: DEFAULT_TX_ID_LENGTH }): Promise<TxId> {\n const lc = `[${getNewTxId.name}]`;\n try {\n length = length || DEFAULT_TX_ID_LENGTH;\n return (await getUUID()).slice(0, length) as TxId;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * wrapper for dealing with a space.\n *\n * convenience function for creating an arg ibgib to send to the given space\n * using Cmd/CmdModifiers for getting latest addrs.\n *\n * @returns space result ibgib from the given `space.witness` call.\n */\nexport async function getLatestAddrs({\n ibGibs,\n addrs,\n tjps,\n tjpAddrs,\n space,\n}: {\n ibGibs?: IbGib_V1[],\n addrs?: IbGibAddr[],\n tjps?: IbGib_V1[],\n tjpAddrs?: IbGibAddr[],\n space: IbGibSpaceAny,\n}): Promise<IbGibSpaceResultIbGib<IbGib_V1, IbGibSpaceResultData, IbGibSpaceResultRel8ns>> {\n let lc = `[${getLatestAddrs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!space) { throw new Error(`space required. (E: 4d188d6c863246f28aa575753a052304)`); }\n\n // so we don't have to do a bunch of conditional checks all over\n ibGibs = ibGibs ?? []; addrs = addrs ?? [];\n tjps = tjps ?? []; tjpAddrs = tjpAddrs ?? [];\n\n if (\n addrs.length === 0 && ibGibs.length === 0 &&\n tjps.length === 0 && tjpAddrs.length === 0\n ) {\n throw new Error(`Either addrs, ibGibs, tjps, or tjpAddrs required. (E: 7c6ebfbab98d4d21a431b144457fd991)`);\n }\n\n /**\n * Addrs that we'll ultimately send to the space. They start off as\n * tjpAddrs (and derived from `tjps` if any), and then add the incoming\n * ibgibs/addrs if we don't already have their corresponding tjpAddrs\n * being queried.\n * */\n const addrsToQuery = new Set<IbGibAddr>(\n tjpAddrs.concat(tjps.map(ibGib => getIbGibAddr({ ibGib })))\n );\n\n // add ibgibs/addrs only if they do not already have their corresponding\n // tjpAddr in the query addrs. We can do this by checking if the tjpGib\n // is located in the ibGibAddr.gib, which has the form\n // [punctiliarHash].[tjpGib]\n const tjpGibs = Array.from(addrsToQuery).map(x => getIbAndGib({ ibGibAddr: x }).gib);\n ibGibs.map(ibGib => getIbGibAddr({ ibGib }))\n .concat(addrs)\n .forEach(ibGibAddr => {\n const { gib } = getIbAndGib({ ibGibAddr });\n const addrHasExistingTjpGib =\n tjpGibs.some(tjpGib => gib.includes(tjpGib));\n if (!addrHasExistingTjpGib) { addrsToQuery.add(ibGibAddr); }\n });\n\n if (logalot) { console.log(`${lc}[testing] ${space.data?.name || space.ib} (${space.data?.uuid || '[space.data.uuid falsy]'}) addrsToQuery: ${Array.from(addrsToQuery)} (I: 8a2202912c364238b6d6eb09577bc246)`); }\n\n // construct the arg and execute\n const argGet = await space.argy({\n ibMetadata: getSpaceArgMetadata({ space }),\n argData: {\n cmd: 'get',\n cmdModifiers: ['latest', 'addrs'],\n ibGibAddrs: Array.from(addrsToQuery),\n },\n });\n return await space.witness(argGet);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * I'm making this because i want to archive on a special tags index ibgib.\n * But we can't allow archiving on any old special ibgib, like the 'roots' index.\n * so this checks to see if it's on the forbidden list (winging that atm), and if it\n * is then this throws.\n *\n * use this function inside of commands that act on ibgibs that are special.\n */\nexport function throwIfContextIsSpecial({\n ibGib_Context,\n}: {\n ibGib_Context: IbGib_V1,\n}): void {\n const lc = `[${throwIfContextIsSpecial.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5f583fd94d27731a65d514e731b8aa22)`); }\n\n if (!isSpecial({ ibGib: ibGib_Context })) { return; /* <<<< returns early */; }\n\n const FORBIDDEN_MANUAL_SPECIAL_TYPES: SpecialIbGibType[] = [\n 'roots', 'autosyncs'\n ];\n if (FORBIDDEN_MANUAL_SPECIAL_TYPES.some(x => ibGib_Context.ib.includes(x))) {\n throw new Error(`cannot perform a modification of this type on this special ibgib (E: b8fb718a7323fc54454464b973412722)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function trash({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n ibGib_Context: IbGib_V1,\n rel8nName_Context: string,\n addr: IbGibAddr,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n const lc = `[${trash.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 2dc486bb2d516e4534f437aaf5ec7f22)`); }\n if (!ibGib_Context) { throw new Error(`ibGib_Context required (E: 75f7bfa93145d6dffe85d488443ca722)`); }\n if (!rel8nName_Context) { throw new Error(`rel8nName_Context required (E: 12aaa43de9e34b68b25dc9a2a68ad6b9)`); }\n if (!addr) { throw new Error(`addr required (E: e27df3bdc5a2554697cc9597afc4e422)`); }\n if (!space) { throw new Error(`space required (E: 2e3562486ed2956a770ed9e8d77a3f22)`); }\n\n const contextIsSpecialIbGib = isSpecial({ ibGib: ibGib_Context });\n if (contextIsSpecialIbGib) { throwIfContextIsSpecial({ ibGib_Context }); }\n\n const resNewContext = await rel8({\n src: ibGib_Context,\n rel8nsToAddByAddr: { [TRASH_REL8N_NAME]: [addr] },\n rel8nsToRemoveByAddr: { [rel8nName_Context]: [addr] },\n dna: true,\n nCounter: true,\n });\n\n await persistTransformResult({ resTransform: resNewContext, space });\n\n if (contextIsSpecialIbGib) {\n const newSpecialAddr = getIbGibAddr({ ibGib: resNewContext.newIbGib });\n const specialType = getSpecialTypeFromIb({ ib: ibGib_Context.ib });\n const configKey = getSpecialConfigKey({ type: specialType });\n await setConfigAddr({ key: configKey, addr: newSpecialAddr, space, zeroSpace, fnUpdateBootstrap });\n }\n\n await registerNewIbGib({ ibGib: resNewContext.newIbGib, fnBroadcast, space, });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function archive({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n}: {\n ibGib_Context: IbGib_V1,\n rel8nName_Context: string,\n addr: IbGibAddr,\n space: IbGibSpaceAny,\n zeroSpace: IbGibSpaceAny,\n fnUpdateBootstrap?: (newSpace: IbGibSpaceAny) => Promise<void>,\n fnBroadcast?: (info: IbGibTimelineUpdateInfo) => void,\n}): Promise<void> {\n const lc = `[${archive.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 38098552b830495187299bb24fcddff0)`); }\n if (!ibGib_Context) { throw new Error(`ibGib_Context required (E: d819e8c4db5b4c0bb721300ba434cd40)`); }\n if (!rel8nName_Context) { throw new Error(`rel8nName_Context required (E: de061adff8c04429a211aa09116a532d)`); }\n if (!addr) { throw new Error(`addr required (E: 7059ebb8ef6149ea94e22f961d6b5c81)`); }\n if (!space) { throw new Error(`space required (E: e19566f2d42347798621447edcae312e)`); }\n\n const contextIsSpecialIbGib = isSpecial({ ibGib: ibGib_Context });\n if (contextIsSpecialIbGib) { throwIfContextIsSpecial({ ibGib_Context }); }\n\n const resNewContext = await rel8({\n src: ibGib_Context,\n rel8nsToAddByAddr: { [ARCHIVE_REL8N_NAME]: [addr] },\n rel8nsToRemoveByAddr: { [rel8nName_Context]: [addr] },\n dna: true,\n nCounter: true,\n });\n\n await persistTransformResult({ resTransform: resNewContext, space });\n\n if (contextIsSpecialIbGib) {\n const newSpecialAddr = getIbGibAddr({ ibGib: resNewContext.newIbGib });\n const specialType = getSpecialTypeFromIb({ ib: ibGib_Context.ib });\n const configKey = getSpecialConfigKey({ type: specialType });\n await setConfigAddr({ key: configKey, addr: newSpecialAddr, space, zeroSpace, fnUpdateBootstrap });\n }\n\n await registerNewIbGib({ ibGib: resNewContext.newIbGib, fnBroadcast, space, });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function spaceNameIsValid(name: string): boolean {\n const lc = `[${spaceNameIsValid.name}]`;\n try {\n // non-falsy\n if (!name) {\n console.error(`${lc} name is falsy`)\n return false;\n }\n\n // valid characters are alphanumerics, numbers, underscores, hyphens\n const regexOnlyIncluded = /[\\w-]+/;\n const matchOnlyIncluded = name.match(regexOnlyIncluded);\n if (matchOnlyIncluded?.length !== 1 || matchOnlyIncluded[0].length !== name.length) {\n console.error(`${lc} name can only contain letters, numbers, underscores, hyphens`);\n return false;\n }\n\n // start with alphanumeric\n const regexStart = /[a-zA-Z\\d]/;\n const matchStart = name[0].match(regexStart);\n if (!matchStart) {\n console.error(`${lc} name must start with a letter or number`);\n return false;\n }\n\n return true;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false;\n }\n}\n\n/**\n * wrapper for getting dependency graph from a space.\n *\n * NOTE: This calls the witness space with the command. This is NOT the\n * same as the logic helper in graph-helper.mts which performs the graph\n * traversal logic potentially in-memory or naively.\n */\nexport async function getDependencyGraph({\n space,\n ibGibAddrs,\n live,\n}: {\n space: IbGibSpaceAny,\n ibGibAddrs: IbGibAddr[],\n live?: boolean,\n}): Promise<{ [addr: string]: IbGib_V1 } | null> {\n const lc = `[${getDependencyGraph.name}]`;\n try {\n if (!space) { throw new Error(`space required (E: 8f2441c099084898953153549725f778)`); }\n if ((ibGibAddrs ?? []).length === 0) { throw new Error(`ibGibAddrs required (E: 9c3b8853609841808093153927649526)`); }\n\n const argData: any = {\n cmd: IbGibSpaceOptionsCmd.get,\n cmdModifiers: [IbGibSpaceOptionsCmdModifier.dependencyGraph],\n ibGibAddrs,\n live,\n };\n const arg = await space.argy({ argData });\n\n const result = await space.witness(arg);\n if (result?.data?.success) {\n const graph: { [addr: string]: IbGib_V1 } = {};\n if (result.ibGibs) {\n for (const ibGib of result.ibGibs) {\n const addr = getIbGibAddr({ ibGib });\n graph[addr] = ibGib;\n }\n }\n return graph;\n } else {\n return null;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "import {\n HashAlgorithm, clone, extractErrorMsg, groupBy, hash, pretty\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs'\nimport { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Ib, IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Factory_V1 } from '@ibgib/ts-gib/dist/V1/factory.mjs';\nimport { GIB, FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES, GIB_DELIMITER, ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { validateIb } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { getGib, getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT, IB_REGEXP_DEFAULT } from '../../core-constants.mjs';\nimport { SpecialIbGibType } from './other-types.mjs';\nimport { INVALID_DATE_STRING, SPECIAL_IBGIB_TYPE_REGEXP } from './other-constants.mjs';\nimport { CONFIG_KEY_ATOM } from './ibgib-constants.mjs';\nimport { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';\nimport { getFromSpace } from '../../witness/space/space-helper.mjs';\nimport { FlatIbGibGraph } from './graph-types.mjs';\nimport { IbGibSpaceResultData } from '../../witness/space/space-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Gets ibgibs that are directly related to the given `ibGib` via `rel8nNames`.\n *\n * @returns map of rel8nName -> ibgibs that are related.\n */\nexport async function getRel8dIbGibs({\n ibGib,\n rel8nNames,\n space,\n}: {\n ibGib: IbGib_V1,\n rel8nNames?: string[],\n space: IbGibSpaceAny,\n}): Promise<{ [rel8nName: string]: IbGib_V1[] }> {\n const lc = `[${getRel8dIbGibs.name}]`;\n try {\n if (!ibGib) { throw new Error(`ibGib required (E: a3c1b2d4e5f6a7b8c9d0e1f2a3b4c5d6)`); }\n if (!space) { throw new Error(`space required (E: b4d2c3e4f5a6b7c8d9e0f1a2b3c4d5e6)`); }\n\n // Default to all rel8n names if none provided\n if (!rel8nNames) {\n rel8nNames = Object.keys(ibGib.rel8ns || {});\n }\n\n const rel8dIbGibs: { [rel8nName: string]: IbGib_V1[] } = {};\n\n for (const rel8nName of rel8nNames) {\n const rel8dAddrs = ibGib.rel8ns?.[rel8nName] || [];\n\n if (rel8dAddrs.length > 0) {\n const resGet = await getFromSpace({ addrs: rel8dAddrs, space });\n if (resGet.success && resGet.ibGibs?.length === rel8dAddrs.length) {\n rel8dIbGibs[rel8nName] = resGet.ibGibs.concat();\n } else {\n // Start logging warnings instead of throwing immediately?\n // For now, consistent with user request to adapt legacy code\n throw new Error(`Problem getting rel8d ibgibs for rel8nName: ${rel8nName}. ${resGet.errorMsg || 'Unknown error'} (E: c5e3d4f5a6b7c8d9e0f1a2b3c4d5e6)`);\n }\n } else {\n rel8dIbGibs[rel8nName] = [];\n }\n }\n\n return rel8dIbGibs;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Utility function to generate hard-coded ibgibs to use at runtime \"on-chain\" but\n * written at compile-time in (for now) \"off-chain\" source code.\n *\n * Because this is supposed to create and re-create deterministically the equivalent\n * of a non-primitive ibgib \"constant\", this function creates a single ibgib with...\n * * one ancestor\n * * no past, dna, or tjp rel8ns\n * * no tjp timestamp or uuid\n * * no nCounter\n *\n * ## validation\n *\n * * validates the given `ib` against `ibRegExpPattern` or default regexp.\n * * validates that rel8ns doesn't include default forbidden rel8n names or\n * atow `'tjp'`.\n *\n * ## intent\n *\n * I want to be able to create deterministic ibGibs that I can reference at\n * runtime, similar to an ibgib primitive (e.g. \"root^gib\"), but with the\n * integrity of the `gib` hash. This way, I can reference a deterministic ibgib\n * from code at compile time, and at runtime this will have a corresponding\n * ibgib datum with gib-hashed integrity.\n *\n * ## example\n *\n * I want to create a \"hard-coded\" schema ibgib that I rel8 to some protocol\n * ibgib. So I'll create the data here, which lives in source control in a text file,\n * and then I'll render that as an ibgib that verifies integrity. If I as a coder change\n * it at all, then the `gib` of course will be different.\n */\nexport async function constantIbGib<\n TData extends IbGibData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n>({\n parentPrimitiveIb,\n ib,\n ibRegExpPattern,\n data,\n rel8ns,\n}: {\n parentPrimitiveIb: Ib,\n ib: Ib,\n /**\n * for checking the constant's generated ib\n */\n ibRegExpPattern?: string,\n data?: TData,\n rel8ns?: TRel8ns,\n}): Promise<IbGib_V1<TData, TRel8ns>> {\n const lc = `[${constantIbGib.name}]`;\n try {\n // validation\n // parentPrimitiveIb\n if (!parentPrimitiveIb) { throw new Error(`parentPrimitiveIb required. (E: 88ddf188cc5a4340b597abefba1481e2)`); }\n if (validateIb({ ib: parentPrimitiveIb }) !== null) { throw new Error(`Invalid parentPrimitiveIb: ${parentPrimitiveIb}. (E:5aec0320956d492ebeeaca41eb1fe1c6)`); }\n\n // ib\n if (!ib) { throw new Error(`ib required. (E: 7bbc88f4f2e842d6b00126e55b1783e4)`); }\n const regExp = ibRegExpPattern ? new RegExp(ibRegExpPattern) : IB_REGEXP_DEFAULT;\n if (!ib.match(regExp)) { throw new Error(`invalid ib. does not match regexp (${regExp})`); }\n\n // rel8ns\n const incomingRel8nNames = Object.keys(rel8ns ?? {});\n const forbiddenRel8nNames = [...FORBIDDEN_ADD_RENAME_REMOVE_REL8N_NAMES, 'tjp'];\n const rel8nsIsInvalid = incomingRel8nNames.some(x => {\n // we don't want constants trying to look like they have/are descendants/tjps/etc.\n return forbiddenRel8nNames.includes(x);\n });\n if (rel8nsIsInvalid) { throw new Error(`Invalid rel8ns. forbiddenRel8nNames: ${forbiddenRel8nNames}. rel8ns keys: ${Object.keys(rel8ns ?? {})}. (E: 837a993c265c4362b6aa0b1a234ea5f8)`); }\n\n\n // create the constant\n const resFirstGen = await Factory_V1.firstGen({\n ib,\n parentIbGib: Factory_V1.primitive({ ib: parentPrimitiveIb }),\n data,\n rel8ns,\n dna: false,\n noTimestamp: true,\n nCounter: false,\n });\n const constantIbGib = resFirstGen.newIbGib as IbGib_V1<TData, TRel8ns>;\n\n // remove any extraneous stuff\n if (constantIbGib?.rel8ns?.past) { delete constantIbGib.rel8ns.past; }\n if (constantIbGib?.rel8ns?.tjp) { delete constantIbGib.rel8ns.tjp; }\n if (constantIbGib?.rel8ns?.identity) { delete constantIbGib.rel8ns.identity; }\n\n // recalculate the gib hash\n // constantIbGib.gib = await sha256v1({\n constantIbGib.gib = await getGib({\n ibGib: {\n ib: constantIbGib.ib,\n data: constantIbGib.data,\n rel8ns: constantIbGib.rel8ns,\n },\n hasTjp: false,\n });\n\n return constantIbGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Binaries require special handling, since they do not conform to the\n * \"normal\" IbGib_V1 data structure per se. This stems from wanting to\n * be able to have binaries (jpgs, gifs, etc. especially) able to\n * sit on a server and be served as regular files.\n *\n * @returns string in expected template for binaries in this app.\n */\nexport function getBinIb({ binHash, binExt, binEncoding }: { binHash: string, binExt?: string, binEncoding?: string }): IbGibAddr {\n if (binEncoding) {\n // adding this part after the fact here. not sure how this is going to\n // go down. just noting because of the strange shape of the logic here.\n return binExt ? `bin ${binHash} ${binExt} enc=${binEncoding}` : `bin ${binHash} enc=${binEncoding}`;\n } else {\n return binExt ? `bin ${binHash} ${binExt}` : `bin ${binHash}`;\n }\n}\n\n/**\n * @deprecated\n *\n * use {@link parseBinIb}\n */\nexport function getBinHashAndExt({ addr }: { addr: IbGibAddr }): { binHash: string, binExt: string, binEncoding?: string } {\n return parseBinIb({ addr });\n}\n\n/**\n * parses a given addr that is expected to be for a {@link BinIbGib_V1}.\n *\n * @throws an error if addr is not for a {@link BinIbGib_V1} (via {@link isBinary})\n *\n * @returns parsed bin ib information\n */\nexport function parseBinIb({ addr }: { addr: IbGibAddr }): { binHash: string, binExt: string, binEncoding?: string } {\n const lc = `[${parseBinIb.name}]`;\n try {\n if (!isBinary({ addr })) { throw new Error(`not a bin address (E: df0804d129bc4888bd6939cb76c5e0f6)`); }\n const { ib } = getIbAndGib({ ibGibAddr: addr });\n const ibPieces = ib.split(' ');\n if (ibPieces.length === 2) {\n // bin ${binHash}\n return {\n binHash: ibPieces[1],\n binExt: '',\n // binEncoding: undefined,\n };\n } else if (ibPieces.length === 3) {\n // could be\n // bin ${binHash} enc=${binEncoding}\n // or...\n // bin ${binHash} ${binExt}\n return ibPieces[2].startsWith(\"enc=\") ?\n {\n binHash: ibPieces[1],\n binExt: '',\n binEncoding: ibPieces[2].substring(\"enc=\".length),\n } :\n {\n binHash: ibPieces[1],\n binExt: ibPieces[2],\n // binEncoding: undefined,\n };\n } else if (ibPieces.length === 4) {\n if (!ibPieces[3].startsWith(\"enc=\")) {\n throw new Error(`bin ib (${ib}) has 4 space-delimited pieces. we expect therefore the form to be bin \\${binHash} \\${binExt} enc=\\${binEncoding}. but ibPieces[3] doesn't start with \"enc=\". (E: 87196d7cdd7c12d982cc8204a1163524)`);\n }\n return {\n binHash: ibPieces[1],\n binExt: ibPieces[2],\n binEncoding: ibPieces[3].substring(\"enc=\".length),\n };\n } else {\n throw new Error(`(UNEXPECTED) ibPieces.length not 2, 3, or 4? atow (01/2024) the only components of a bin ib are: atom, binHash, binExt, binEncoding. binExt and binEncoding are optional, with binEncoding being prefixed with \"enc=\". (E: b05df3c1b3949f76464a83c9fd1c4f24)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * atow (01/2024) this looks to see...\n *\n * * that data is truthy (if ibGib is truthy)\n * * gib is a UUID\n *\n * ## dev note\n *\n * this is tightly coupled with {@link getBinIb} and {@link parseBinIb}\n *\n * @returns true if analysis of ibgib indicates it is a {@link BinIbGib_V1}, else false\n */\nexport function isBinary({\n ibGib,\n addr,\n}: {\n ibGib?: IbGib_V1,\n addr?: IbGibAddr,\n}): boolean {\n const lc = `[${isBinary.name}]`;\n try {\n // probably overkill here, but...\n if (!ibGib && !addr) { throw new Error(`either ibGib or addr required. (E: c935b51e773f41a2a547c556e9dc16c6)`); }\n if (ibGib && !ibGib.data) { return false; }\n addr = addr || getIbGibAddr({ ibGib });\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n if (!ib) { return false; }\n if (!gib) { return false; }\n if (!ib.startsWith('bin ')) { return false; }\n\n // at this point any weirdness throws an error, because the ib plainly\n // indicates this is a bin ibgib.\n\n if (gib.length !== 64) {\n throw new Error(`ib starts with \"bin \" but gib length is not 64, so return false. Two things: 1) bin ibgibs are expected to be stones, i.e., have no temporal junction point and only a single punctiliar hash for the gib. the default hash used atow (01/2024) is sha-256, so the length should be 64. But this may not be true if using another hash algorithm. need to change this function when this becomes the case. (W: 60725d65d13c4b4fbb7b96d7feb19d67)`);\n }\n\n // tightly coupled here with parsing algorithm\n\n const ibPieces = ib.split(' ');\n if (ibPieces.length === 2) {\n // bin ${binHash}\n if (!ibPieces[1].match(UUID_REGEXP)) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[1].match(UUID_REGEXP)? (E: f6baca2ff155f1017b278a5d7597a224)`);\n }\n } else if (ibPieces.length === 3) {\n // could be\n // bin ${binHash} enc=${binEncoding}\n // or...\n // bin ${binHash} ${binExt}\n if (!ibPieces[1].match(UUID_REGEXP)) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[1].match(UUID_REGEXP)? (E: 8d0443d6cada4b50be79a8390a7a426c)`);\n }\n } else if (ibPieces.length === 4) {\n if (!ibPieces[1].match(UUID_REGEXP)) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[1].match(UUID_REGEXP)? (E: 3209eacc0a3848a59593d4c3ee956191)`);\n }\n // bin ${binHash} ${binExt} enc=${binEncoding}\n if (!ibPieces[3].startsWith(\"enc=\")) {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited !ibPieces[3].startsWith(\"enc=\")? (E: 4c8a0c3b07a90d30e3d1a4373d57d824)`);\n }\n } else {\n throw new Error(`(UNEXPECTED) ib starts with \"bin \" but space-delimited ibPieces length is not 2, 3 or 4? (E: c7eccf88518304997c7e42b32e08d224)`);\n }\n\n // passed gauntlet\n return true;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Recursively hashes some string {@link recursionCount} number of times.\n */\nexport async function hash16816({\n s,\n algorithm,\n recursionCount,\n saltPrependedPerHash,\n}: {\n /**\n * string to hash\n */\n s: string,\n /**\n * algorithm to use. defaults to 'SHA-256'\n */\n algorithm: HashAlgorithm,\n /**\n * number of recursions to do. Defaults to 16816.\n */\n recursionCount: number,\n saltPrependedPerHash: string,\n}): Promise<string> {\n const lc = `[${hash16816.name}]`;\n try {\n saltPrependedPerHash ??= '';\n recursionCount ??= 16816;\n algorithm ??= 'SHA-256';\n let hashed: string = '';\n if (saltPrependedPerHash) {\n for (let i = 0; i < recursionCount; i++) {\n hashed = await hash({ s: saltPrependedPerHash + s, algorithm });\n }\n } else {\n for (let i = 0; i < recursionCount; i++) {\n hashed = await hash({ s, algorithm });\n }\n }\n return hashed;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * creates atow (10/2023) space-delimited ib in the form of `meta special ${type}`.\n *\n * @returns ib for given `type`\n * @throws error if `type` doesn't match {@link SPECIAL_IBGIB_TYPE_REGEXP}\n *\n * @see {@link getSpecialTypeFromIb}\n * @see {@link SPECIAL_IBGIB_TYPE_REGEXP}\n */\nexport function getSpecialIbGibIb({ type }: { type: SpecialIbGibType }): Ib {\n if (!type.match(SPECIAL_IBGIB_TYPE_REGEXP)) {\n throw new Error(`special ibgib type must not have spaces and just be alphanumerics. regexp: ${SPECIAL_IBGIB_TYPE_REGEXP.source} (E: 6c1c92521b7f076cc4666e4915593723)`);\n }\n return `meta special ${type}`;\n}\n\n/**\n * extracts the {@link SpecialIbGibType} from the given `ib`.\n *\n * @returns type {@link SpecialIbGibType}\n *\n * @see {@link getSpecialIbGibIb}\n * @see {@link SPECIAL_IBGIB_TYPE_REGEXP}\n */\nexport function getSpecialTypeFromIb({ ib }: { ib: Ib }): SpecialIbGibType {\n const lc = `[${getSpecialTypeFromIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c82ba222bd345ee6b695df4d63a23322)`); }\n if (!ib) { throw new Error(`ib required (E: 08897145f7138e644fe01c4a59353322)`); }\n if (!isSpecial({ ib })) { throw new Error(`ib is not special (E: 174aff63b992adff3ac2394643735922)`); }\n const pieces = ib.split(' ');\n if (pieces.length < 3) { throw new Error(`invalid ib. should be space-delimited in form of \"meta special [type]\" (E: ffd89e2cbe63427f98634ab897aab222)`); }\n const specialType = pieces[2];\n if (!Object.values(SpecialIbGibType).some(x => x === specialType)) {\n console.warn(`unknown special type (${specialType}). This may be expected, but atow I am adding special types to the SpecialIbGibType enum-like. (W: f4e26c3ebb57fe49d69014a4ba32a922)`);\n }\n return (specialType as SpecialIbGibType);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * gets a special ib and tacks on ^gib for a constant address.\n *\n * used in primitives (ancestors for special ibgibs), as well as as of atow\n * (11/2023) the \"latest\" special ibgib.\n *\n * @returns special IbGibAddr\n */\nexport function getSpecialIbGibAddr({ type }: { type: SpecialIbGibType }): string {\n const ib = getSpecialIbGibIb({ type });\n return `${ib}^${GIB}`;\n}\n\nexport function getSpecialConfigKey({ type }: { type: SpecialIbGibType }): string {\n return `${CONFIG_KEY_ATOM} ${getSpecialIbGibAddr({ type })}`;\n}\n\nexport function isSpecial({ ib, ibGib }: { ib?: Ib, ibGib?: IbGib_V1 }): boolean {\n if (!ib && !ibGib?.ib) { throw new Error(`either ib or ibGib.ib required (E: b4cf539638d7966c2e351987f55e1a23)`); }\n return (ib ?? ibGib?.ib)?.startsWith('meta special')!;\n}\n\n/**\n * returns ib for a given root. ATOW this is simply \"root {text}\"\n *\n * @returns ib for the given rootText\n */\nexport function getRootIb(rootText: string): string {\n const lc = `[${getRootIb.name}]`;\n if (!rootText) { throw new Error(`${lc} text required.`) }\n return `root ${rootText}`;\n}\n\n/**\n * Tags for this app have the form: tag [tagText]\n *\n * @param tagText e.g. \"Favorites\"\n *\n * @example\n * For the Favorites tag, the ib would be \"tag Favorites\"\n */\nexport function tagTextToIb(tagText: string): string {\n const lc = `[${tagTextToIb.name}]`;\n if (!tagText) { throw new Error(`${lc} tag required.`) }\n return `tag ${tagText}`;\n}\n\n/**\n * Living: has tjp and dna.\n * Stones: does not have Dna, maybe has tjp.\n *\n * Splits the given `ibGibs` into two maps, one that includes the ibgibs that\n * have a tjp (temporal junction point) AND dna (\"living\") and those that do not\n * have both tjp AND dna (\"stones\").\n *\n * ## notes\n *\n * Having dna implies having a tjp, but the reverse is not necessarily true.\n * Sometimes you want an ibgib that has a tjp so you can, e.g., reference the\n * entire timeline easily. But at the same time you don't want to keep track of\n * the transforms, perhaps this is because you don't want to be able to merge\n * timelines.\n */\nexport function splitPerTjpAndOrDna({\n ibGibs,\n filterPrimitives,\n}: {\n ibGibs: IbGib_V1[],\n filterPrimitives?: boolean,\n}): {\n /** ibgibs have both tjp and dna */\n mapWithTjp_YesDna: { [gib: string]: IbGib_V1 },\n /** ibgibs have tjp but NO dna */\n mapWithTjp_NoDna: { [gib: string]: IbGib_V1 },\n /** ibgibs that have no tjp (and implicitly no dna) */\n mapWithoutTjps: { [gib: string]: IbGib_V1 }\n} {\n const lc = `[${splitPerTjpAndOrDna.name}]`;\n try {\n const mapWithTjp_YesDna: { [gib: string]: IbGib_V1 } = {};\n const mapWithTjp_NoDna: { [gib: string]: IbGib_V1 } = {};\n const mapWithoutTjps: { [gib: string]: IbGib_V1 } = {};\n // const mapLivingIbGibs: { [gib: string]: IbGib_V1 } = {};\n // const mapStoneIbGibs: { [gib: string]: IbGib_V1 } = {};\n const ibGibsTodo = filterPrimitives ?\n ibGibs.filter(ibGib => ibGib.gib ?? ibGib.gib !== GIB) :\n ibGibs;\n ibGibsTodo.forEach(ibGib => {\n if (hasTjp({ ibGib })) {\n if ((ibGib.rel8ns?.dna ?? []).length > 0) {\n mapWithTjp_YesDna[ibGib.gib!] = ibGib;\n } else {\n mapWithTjp_NoDna[ibGib.gib!] = ibGib;\n }\n } else {\n mapWithoutTjps[ibGib.gib!] = ibGib;\n }\n });\n return { mapWithTjp_YesDna, mapWithTjp_NoDna, mapWithoutTjps };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Takes incoming `ibGibs`, filters out those that do\n * not have tjps( i.e. non-timelines), and groups\n * the timeline ibgibs by tjp in ascending order.\n *\n * This means that each map entry will be in the form:\n * `[tjpAddr] => [ibgib0 (tjp), ibgib1, ibgib2, ..., ibgibN (latest)]`\n *\n * ## notes\n *\n * * sorts by `ibgib.data.n`. If this is undefined, will not sort in ascending\n * order properly.\n *\n * @returns filtered, sorted map of incoming `ibGibs` [tjpAddr] => timeline [ibgib0 (tjp), ibgib1, ibgib2, ..., ibgibN (latest)]\n */\nexport function getTimelinesGroupedByTjp({\n ibGibs,\n}: {\n /**\n * group of source ibGibs to filter/group/sort by tjp.\n */\n ibGibs: IbGib_V1[],\n}): { [tjpAddr: string]: IbGib_V1[] } {\n const lc = `[${getTimelinesGroupedByTjp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // pull out only the ibgibs in timelines (either is tjp or has tjp)\n let { mapWithTjp_YesDna, mapWithTjp_NoDna } =\n splitPerTjpAndOrDna({ ibGibs, filterPrimitives: true });\n const mapIbGibsWithTjp = { ...mapWithTjp_YesDna, ...mapWithTjp_NoDna };\n const ibGibsWithTjp = Object.values(mapIbGibsWithTjp);\n\n const mapTjpTimelines_Ascending = groupBy({\n items: ibGibsWithTjp,\n keyFn: x => {\n // x.data?.isTjp ? getIbGibAddr({ ibGib: x }) : (x.rel8ns?.tjp[0] ?? '') // converting this untested...hmm\n if (x.data?.isTjp) {\n return getIbGibAddr({ ibGib: x });\n } else if (x.rel8ns?.tjp) {\n return x.rel8ns?.tjp[0] ?? '';\n } else {\n if (logalot) { console.log(`${lc} neither isTjp nor x.rel8ns.tjp truthy (I: ec9a5597bf53dec1bd3d83350abbf823)`); }\n return '';\n }\n\n }\n });\n\n if (logalot) { console.log(`${lc} sorting (ascending) ibGibsWithTjpGroupedByTjpAddr: ${pretty(mapTjpTimelines_Ascending)} (I: 9b9fff5ce61444a6cb06d62db9a99422)`); }\n Object.entries(mapTjpTimelines_Ascending).forEach(([_tjpAddr, timeline]) => {\n if (timeline.some(ibGib => ibGib.data?.n === undefined)) {\n console.warn(`${lc} timeline includes ibgibs with ibGib.data?.n === undefined (W: cab9a6b64a38c4279fe82c3569bbab22)`);\n }\n // sort mutates array in place\n timeline.sort((a, b) => (a.data?.n ?? -1) > (b.data?.n ?? -1) ? 1 : -1); // sorts ascending, e.g., 0,1,2...[Highest]\n });\n if (logalot) { console.log(`${lc} after sort ibGibsWithTjpGroupedByTjpAddr: ${pretty(mapTjpTimelines_Ascending)} (I: 9b9fff5ce61444a6cb06d62db9a99422)`); }\n\n return mapTjpTimelines_Ascending; // ascending\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Helper function that checks the given `ibGib` to see if it\n * either has a tjp or is a tjp itself.\n *\n * ## notes\n *\n * Only unique ibGibs are meant to have tjps, or rather, if an\n * ibGib timeline is expected to be unique over \"time\", then the\n * tjp is an extremely convenient mechanism that provides a\n * \"name\" for that timeline.\n *\n * Otherwise, if they are not unique, then successive \"different\"\n * timelines cannot be easily referenced by their first unique\n * frame in time, making it much harder to pub/sub updates among\n * other things. (If there are no unique frames, then they are\n * the same ibGib.)\n *\n * ## tjp = temporal junction point\n *\n * I've written elsewhere on this as well. Refer to B2tF2.\n *\n * @returns true if the ibGib has/is a tjp, else false\n */\nexport function hasTjp({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${hasTjp.name}]`;\n\n if (!ibGib) { throw new Error(`(UNEXPECTED) ibGib falsy? (E: ce3a59f9db14e6158bb2c438ca1a3823)`); }\n\n // most likely is that rel8ns.tjp has an entry or the internal data.isTjp\n if ((ibGib.rel8ns?.tjp?.length ?? 0) > 0 || ibGib.data?.isTjp) {\n return true; /* <<<< returns early */\n }\n\n // dna transforms do not have tjp\n const dnaPrimitives = ['fork^gib', 'mut8^gib', 'rel8^gib'];\n if ((ibGib.rel8ns?.ancestor ?? []).some(x => dnaPrimitives.includes(x))) {\n return false; /* <<<< returns early */\n }\n\n if (!ibGib.gib) {\n console.warn(`${lc} ibGib.gib falsy. (W: 6400d780822b44d992846f1196509be3)`);\n return false; /* <<<< returns early */\n }\n if (ibGib.gib.includes(GIB_DELIMITER)) {\n return true; /* <<<< returns early */\n }\n\n if (ibGib.gib === GIB) {\n // primitive\n return false; /* <<<< returns early */\n }\n\n // at this point, we've already determined most likely what the result is.\n // definitively, we'll pass the buck to getGibInfo in case implementation\n // details change in the future. it is a more expensive call. could\n // possibly just return false at this point, but since gib info would change\n // if we change our standards for gib, this is nicer.\n const gibInfo = getGibInfo({ ibGibAddr: getIbGibAddr({ ibGib }) });\n return !!gibInfo.tjpGib;\n}\n\nexport function hasDna({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${hasDna.name}]`;\n\n if (!ibGib) {\n console.warn(`${lc} ibGib falsy. (W: 5fd19751f5c84da59d83dd33487ed859)`);\n return false;\n }\n\n return (ibGib.rel8ns?.dna ?? []).length > 0;\n}\n\n/**\n * Extracts the tjp addr from the ibgib record. If there is no tjp addr found,\n * then refers to `defaultIfNone` arg to determine if it returns undefined or\n * the incoming ibgib's addr.\n * @returns extracted tjp addr or undefined, depending on if found and defaultIfNone value\n */\nexport function getTjpAddr({\n ibGib,\n defaultIfNone = 'undefined',\n}: {\n ibGib: IbGib_V1,\n defaultIfNone?: 'incomingAddr' | 'undefined',\n}): IbGibAddr | undefined {\n const lc = `[${getTjpAddr.name}]`;\n try {\n const tjpMap = getTjpAddrs({ ibGibs: [ibGib], defaultIfNone });\n return tjpMap && Object.keys(tjpMap).length === 1 ? Object.values(tjpMap)[0] : undefined;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * builds a map of the given ibgib's addrs to each's corresponding tjp addr.\n *\n * @returns a map of ibgib addr -> tjp addr\n */\nexport function getTjpAddrs({\n ibGibs,\n defaultIfNone = 'undefined',\n}: {\n ibGibs: IbGib_V1[],\n defaultIfNone?: 'incomingAddr' | 'undefined',\n}): { [ibGibAddr: IbGibAddr]: IbGibAddr | undefined } {\n const lc = `[${getTjpAddrs.name}]`;\n try {\n const resultMap: { [ibGibAddr: IbGibAddr]: IbGibAddr | undefined } = {};\n\n ibGibs.forEach(ibGib => {\n let ibGibAddr = getIbGibAddr({ ibGib });\n let tjpAddr: IbGibAddr | undefined;\n if (ibGib.rel8ns?.tjp?.length ?? 0 > 0) {\n // get the last tjp addr atow\n tjpAddr = ibGib.rel8ns!.tjp![ibGib.rel8ns!.tjp!.length - 1];\n } else if (ibGib.data?.isTjp || defaultIfNone === 'incomingAddr') {\n // either the incoming addr is the tjp or we're defaulting to it per defaultIfNone arg\n tjpAddr = ibGibAddr;\n } else {\n // explicitly set to undefined per defaultIfNone arg\n tjpAddr = undefined;\n }\n resultMap[ibGibAddr] = tjpAddr;\n });\n\n return resultMap;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Returns true if the given {@param ibGib} is the temporal junction\n * point for a given ibGib timeline.\n */\nexport async function isTjp_Naive({\n ibGib,\n naive = true,\n}: {\n ibGib: IbGib_V1<any>,\n naive?: boolean,\n}): Promise<boolean> {\n const lc = `[${isTjp_Naive.name}]`;\n try {\n if (!ibGib) { throw new Error('ibGib required.'); }\n if (naive) {\n if (ibGib.data) {\n if (ibGib.data.isTjp) { return true; }\n if (!ibGib.rel8ns) {\n if (logalot) { console.log(`${lc} ibGib.rel8ns falsy (I: c69c9e78b34845311ce7c674d7195622)`); }\n return false;\n }\n if (ibGib.rel8ns.past && ibGib.rel8ns.past.length > 0) { return false; }\n if (ibGib.rel8ns.past && ibGib.rel8ns.past.length === 0) { return true; }\n return false;\n } else {\n throw new Error('loaded ibGib required (data).');\n }\n } else {\n throw new Error('only naive implemented right now.');\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\nexport function toDto<TData = IbGibData_V1, TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1>({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): IbGib_V1<TData, TRel8ns> {\n const lc = `[${toDto.name}]`;\n if (!ibGib.ib) { console.warn(`${lc} ibGib.ib is falsy. (W: e60e41c2a1fc48268379d88ce13cb77b)`); }\n if (!ibGib.gib) { console.warn(`${lc} ibGib.gib is falsy. (W: fb3889cbf0684ae4ac51e48f28570377)`); }\n\n\n let dtoIbGib: IbGib_V1<TData, TRel8ns> = { ib: (ibGib.ib || '').slice() };\n if (ibGib.gib) { dtoIbGib.gib = ibGib.gib.slice(); };\n if (ibGib.data) {\n if (isBinary({ ibGib })) {\n // binary has data of Uint8Array atow (02/2024)\n dtoIbGib.data = (ibGib.data as Uint8Array).slice() as any;\n } else {\n dtoIbGib.data = clone(ibGib.data);\n }\n }\n if (ibGib.rel8ns) { dtoIbGib.rel8ns = clone(ibGib.rel8ns); }\n\n return dtoIbGib;\n}\n\n/**\n * helpful for differentiating discriminated unions.\n *\n * technically, atow, anything with an ib meets the minimum requirements for an\n * ibgib. this is because you can think of any value as being a metadata\n * \"header\" with other derivative & metadatas as being absent.\n *\n * For example, a string value \"my string yo\" is all you have to go on if you\n * don't have a hash which would be metadata about that value. its address would\n * be \"my string yo^gib\" as it's a primitive, and its intrinisic data would just\n * be a duplicate of the ib, so it's left undefined, and there are no extrinsic\n * rel8ns so rel8ns would be undefined.\n *\n * ## driving use case\n *\n * In doing rxjs replacement, I'm needing to tell if an error coming down the\n * pipe is ErrorIbGib_V1 | Error | string.\n *\n * @param obj any object. note: if falsy, returns false\n * @returns true if the obj is an ibgib, else false\n */\nexport function isIbGib(obj: any): boolean {\n const lc = `[${isIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 57aef93fc6cc2309523b5c72a6b11823)`); }\n // technically\n return !!obj && typeof obj.ib === 'string';\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * extracts timestamp info from the given `ibGib`.\n *\n * ## about\n *\n * not all ibGibs have timestamps (data.timestamp) and they may be in the form\n * of a timestamp string. this may actually be a timestamp string for a Date\n * object or it could be a string of ticks from date.getTime(). or maybe\n * downstream someone just does a number instead of a string.\n *\n * so this function is supposed to be good at figuring this out given an\n * `ibGib`.\n *\n * ## todo\n *\n * 1. we could add an optional path parameter that allows us to specify the\n * path(s) of things that should be timestamps.\n *\n * 2. we could have a simple extractTimestamp(value: any) that does the same\n * thing and then call that from this function.\n *\n * @returns info object that has the timestamp in various formats (if valid) or an error msg (if invalid)\n */\nexport function getTimestampInfo({\n ibGib,\n data,\n timestamp,\n}: {\n // /**\n // * ibGib from which we are extracting timestamp info.\n // */\n ibGib?: IbGib_V1;\n data?: IbGibData_V1;\n timestamp?: string;\n}): {\n valid: true;\n date: Date,\n utc: string,\n ticks: string,\n ms: number | undefined;\n} | {\n valid: false;\n emsg: string;\n} {\n const lc = `[${getTimestampInfo.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 35cb68744bcf6139d78e37de644fad23)`); }\n\n timestamp = timestamp || data?.timestamp || ibGib?.data?.timestamp;\n const ms = ibGib?.data?.timestampMs || data?.timestampMs;\n\n // ensure timestamp truthy\n if (!timestamp) {\n const emsg = `${lc} timestamp is falsy. (W: 5f1f1182c8804807b886a3d922ac3dcf)`;\n console.warn(emsg);\n return { valid: false, emsg }; /* <<<< returns early */\n }\n\n // we have a timestamp, but no idea what it actually is. supposed to be\n // a string with either a utc timestamp or a number, but check for other\n // cases as well\n\n // try it as a timestamp string\n if (typeof timestamp === 'string') {\n if (Number.isInteger(Number.parseInt(timestamp))) {\n\n // #region maybe ticks string\n const parsedTimestamp = Number.parseInt(timestamp);\n let date = new Date();\n date.setTime(parsedTimestamp);\n if (date.toString() !== INVALID_DATE_STRING) {\n // valid timestampInTicks string\n if (logalot) { console.log(`${lc} valid timestampInTicks string (I: 7069a1c3047f3bbc92b78674b20f5b23)`); }\n return {\n valid: true,\n date,\n utc: date.toUTCString(),\n ticks: date.getTime().toString(),\n ms,\n }; /* <<<< returns early */\n } else {\n const emsg = `${lc} data.timestamp (${timestamp}) is an integer string but not a valid timestampInTicks string. (produces invalid date) (E: f49fbb600fe1426c8805dfc8afbe5cf3)`;\n console.error(emsg);\n return { valid: false, emsg }; /* <<<< returns early */\n }\n // #endregion maybe ticks string\n } else {\n // #region maybe timestamp string\n let date = new Date(timestamp);\n if (date.toString() !== INVALID_DATE_STRING) {\n // valid timestamp string (may or may not be UTC)\n return {\n valid: true,\n date,\n utc: date.toUTCString(),\n ticks: date.getTime().toString(),\n ms,\n }; /* <<<< returns early */\n } else {\n const emsg = `${lc} data.timestamp is a non-integer string but not a valid date timestamp string (new date instantiated produces invalid date). (W: c6c90f7f3bfb49838d2081ba84fdb5fb)`;\n console.warn(emsg)\n return { valid: false, emsg }; /* <<<< returns early */\n }\n // #endregion maybe timestamp string\n }\n } else if (typeof (timestamp as any) === 'number') {\n if (Number.isInteger(timestamp)) {\n console.warn(`${lc} expected data.timestamp to be a string but is a number (W: 9d786f4d4e8d4279b5af7bee19bf721b)`);\n let date = new Date();\n date.setTime(timestamp as number);\n if (date.toString() !== INVALID_DATE_STRING) {\n // valid timestamp string\n return {\n valid: true,\n date,\n utc: date.toUTCString(),\n ticks: date.getTime().toString(),\n ms,\n }; /* <<<< returns early */\n } else {\n const emsg = `${lc} timestamp (${timestamp}) is an integer number but not a valid timestampInTicks (new date setTime produces invalid date). (W: c6c90f7f3bfb49838d2081ba84fdb5fb)`;\n console.warn(emsg)\n return { valid: false, emsg }; /* <<<< returns early */\n }\n } else {\n // number but not integer? hmm\n const emsg = `${lc} timestamp (${timestamp}) is a non-integer number (supposed to be a string either timestamp string or ticks). (E: 2963d95f8d3b464c992b0bff948b4479)`;\n console.error(emsg)\n return { valid: false, emsg }; /* <<<< returns early */\n }\n } else {\n const emsg = `${lc} unknown typeof timestamp (${typeof timestamp}). (E: 12458a9c16c84e4f859b5771a30dd2ef)`;\n console.error(emsg);\n return { valid: false, emsg }; /* <<<< returns early */\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * First we combine {@link readCache_graph} and {@link readCache_array} into\n * one unified cache. This can even be empty (if both empty/falsy).\n *\n * Then looks in {@link space} for all other addrs (throws if *any* not found).\n *\n * Then creates the result array, which will be in the same order as incoming\n * {@link addrs} (so this acts like a fancy .map() call).\n *\n * @throws if any addr is not found\n *\n * ## notes\n *\n * Since you can pass in empty cache(s), you can actually use this as a generic\n * getIbGibs function that throws if you don't want to use `getFromSpace` and\n * parse the results. (which is what I find I want more and more the lazier I\n * get).\n */\nexport async function getIbGibsFromCache_fallbackToSpaces({\n addrs,\n readCache_graph,\n readCache_array,\n space,\n}: {\n addrs: IbGibAddr[],\n readCache_graph?: FlatIbGibGraph,\n readCache_array?: IbGib_V1[],\n space: IbGibSpaceAny,\n}): Promise<IbGib_V1[]> {\n const lc = `[${getIbGibsFromCache_fallbackToSpaces.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5db66871239dfa05182277f886a20926)`); }\n readCache_graph ??= {};\n readCache_array ??= [];\n\n /**\n * we're going to put all ibgibs into this graph. IOW, we'll start with\n * incoming caches, then get all other addrs not found here from the\n * space in a single call. At that point, we'll be able to create the\n * result array.\n */\n const allIbGibs_graph = { ...readCache_graph };\n readCache_array.forEach(x => allIbGibs_graph![getIbGibAddr({ ibGib: x })] = x);\n\n const allCachedAddrs = Object.keys(readCache_graph);\n const addrsNotFoundInCache = addrs.filter(x => !allCachedAddrs.includes(x));\n\n\n if (addrsNotFoundInCache.length > 0) {\n if (logalot) { console.log(`${lc} ${addrsNotFoundInCache.length} addrsNotFoundInCache: ${addrsNotFoundInCache} (I: fccbd18116ffb849f813aaebfc6c0826)`); }\n\n /**\n * I changed this to spaces for a workaround but I am putting back\n * the signature to the single space. But I kind of like the idea of\n * this being able to pull from multiple spaces, so I'm leaving the\n * logic here for future.\n */\n const spaces = [space];\n let addrsStillNotFound = addrsNotFoundInCache.concat();\n for (const space of spaces) {\n const resGet = await getFromSpace({ addrs: addrsStillNotFound, space });\n if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === addrsStillNotFound.length) {\n resGet.ibGibs.forEach(x => allIbGibs_graph![getIbGibAddr({ ibGib: x })] = x);\n addrsStillNotFound = [];\n } else {\n // might have gotten some ibgibs\n if (resGet.ibGibs && resGet.ibGibs.length > 0) {\n addrsStillNotFound =\n addrsStillNotFound.filter(addr =>\n !resGet.ibGibs!.some(gottenIbGib => getIbGibAddr({ ibGib: gottenIbGib }) === addr)\n );\n if (addrsStillNotFound.length === 0) {\n break;\n }\n } else {\n if (logalot) { console.log(`${lc} no addrs found in space (${space.ib}). trying next space. (I: 4f99d8bacbb10ab3f8737a752564b326)`); }\n }\n }\n }\n\n if (addrsStillNotFound.length > 0) {\n throw new Error(`could not get all addrs from cache or spaces. addrsStillNotFound: ${addrsStillNotFound}. spaces: ${spaces.map(x => x.ib).join('|')} (E: 0c6418f83dd85bda886e56f5b98f3126)`);\n }\n }\n\n // at this point, we're guaranteed to have all addrs in allIbGibs_graph,\n // but we will still check\n\n const resIbGibs: IbGib_V1[] = [];\n for (const addr of addrs) {\n // refactor this later to be less defensive if this stands the test\n // of time. (ATOW 01/28/2026)\n const ibGib = allIbGibs_graph[addr];\n if (!ibGib) { throw new Error(`(UNEXPECTED) allIbGibs_graph doesn't have addr? We're expecting logic to preclude this at this point. addr: ${addr} (E: f68e1d236ae5e3eb08da9933c8230626)`); }\n resIbGibs.push(ibGib);\n }\n\n return resIbGibs;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * naive general purpose helper guard function based off of a given ibgib's\n * `ib` property.\n *\n * uses conventional V1 `ib` schema, expecting space-delimited `ib` with the\n * first piece being the atom.\n *\n * @param x - any object, usually known to be an ibgib\n * @param atom - the expected atom that determines the type of ibgib\n * @returns true if `x.ib` contains `atom` and thus is `TIbGib`, else false\n */\nexport function isIbGibWithAtom<TIbGib extends IbGib_V1>(x: any, atom: string): x is TIbGib {\n const lc = `[${isIbGibWithAtom.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e946f8ca70b65e6968bd8e78aa473826)`); }\n\n if (!x.ib) {\n return false; /* <<<< returns early */\n }\n\n if (typeof x.ib !== 'string') {\n return false; /* <<<< returns early */\n }\n\n const [pieceAtom, ...otherPieces] = x.ib.split(' ');\n\n if (atom !== pieceAtom) {\n return false; /* <<<< returns early */\n }\n\n return true;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "export const GLOBAL_LOG_A_LOT = false;\nexport const GLOBAL_TIMER_NAME = '[node^gib timer]';\n", "import { existsSync, mkdirSync } from 'node:fs';\nimport { writeFile, rm, readdir } from 'node:fs/promises';\nimport { default as pathUtils } from 'path';\n\nimport { clone, extractErrorMsg, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { getGib, getGibInfo, } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport {\n IbGib_V1, IbGibRel8ns_V1,\n} from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Gib, Ib, IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { validateIbGibAddr } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { IBGIB_DELIMITER } from '@ibgib/ts-gib/dist/V1/constants.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '@ibgib/core-gib/dist/core-constants.mjs';\nimport { isBinary, parseBinIb, toDto, } from '@ibgib/core-gib/dist/common/other/ibgib-helper.mjs';\nimport { getSpaceIb, } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';\nimport {\n DeleteIbGibFileOpts, DeleteIbGibFilesResult,\n GetIbGibFileOpts,\n GetIbGibFileResult,\n PutIbGibFileOpts,\n PutIbGibFileResult\n} from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-types.mjs';\nimport {\n IBGIB_BASE_SUBPATH, IBGIB_SPACE_SUBPATH_DEFAULT, IBGIB_BASE_DIR,\n IBGIB_ENCODING, IBGIB_IBGIBS_SUBPATH, IBGIB_META_SUBPATH,\n IBGIB_BIN_SUBPATH,\n IBGIB_DNA_SUBPATH,\n DEFAULT_LONG_PATH_LENGTH,\n IBGIB_LONG_SUBPATH,\n} from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';\nimport { FilesystemSpace_V1, } from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-space-v1.mjs';\nimport { tryRead, tryRead_bin } from './node-filesystem-space-helper.mjs';\nimport {\n NodeFilesystemSpaceData_V1, NodeFilesystemSpaceRel8ns_V1,\n NodeFilesystemSpaceOptionsData, NodeFilesystemSpaceOptionsRel8ns, NodeFilesystemSpaceOptionsIbGib,\n NodeFilesystemSpaceResultData, NodeFilesystemSpaceResultRel8ns,\n DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1,\n FileDataInfo,\n} from './node-filesystem-space-types.mjs';\nimport { META_STONE_ATOM } from '@ibgib/core-gib/dist/common/meta-stone/meta-stone-constants.mjs';\nimport { isMetaStone, validateCommonMetaStoneIb } from '@ibgib/core-gib/dist/common/meta-stone/meta-stone-helper.mjs';\nimport { BinIbGib_V1 } from '@ibgib/core-gib/dist/common/bin/bin-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Base class convenience for a local space with V1 ibgibs working with the node\n * filesystem.\n *\n * Unfortunately, file systems have short file name requirements, where 255 is\n * often the max length of a filename. So this cannot store ibgibs directly by\n * their address.\n *\n * This naively caches ibGibs in memory. When not found there, will looks in\n * files using Ionic `FileSystem`.\n */\nexport class NodeFilesystemSpace_V1<\n TData extends NodeFilesystemSpaceData_V1 = NodeFilesystemSpaceData_V1,\n TRel8ns extends NodeFilesystemSpaceRel8ns_V1 = NodeFilesystemSpaceRel8ns_V1\n> extends FilesystemSpace_V1<\n NodeFilesystemSpaceOptionsData,\n NodeFilesystemSpaceOptionsRel8ns,\n NodeFilesystemSpaceResultData,\n NodeFilesystemSpaceResultRel8ns,\n TData,\n TRel8ns\n> {\n\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${NodeFilesystemSpace_V1.name}]`;\n\n /**\n * in case the caller tries to override the classname. This should be overridden in any descendant classes\n */\n get classname(): string { return NodeFilesystemSpace_V1.name; }\n\n constructor(\n // /**\n // * Default predicate value when putting an unknown ibGib.\n // *\n // * ## notes\n // *\n // * So when a repo witnesses another ibGib, it either defaults to\n // * storing that ibGib or not storing that ibGib. This is what that\n // * is referring to. If it's optimistic, then it stores any ibGib by\n // * default and it passes its put predicate.\n // */\n // public optimisticPut: boolean = true,\n initialData?: TData,\n initialRel8ns?: TRel8ns,\n ) {\n super(initialData ?? clone(DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1), initialRel8ns);\n const lc = `${this.lc}[ctor]`;\n\n // try {\n // if (logalot) { console.log(`${lc} starting...`); }\n // this.initialize();\n // } catch (error) {\n // console.error(`${lc} ${extractErrorMsg(error)}`);\n // throw error;\n // } finally {\n // if (logalot) { console.log(`${lc} complete.`); }\n // }\n }\n\n /**\n * Factory static method to create the space with the given\n * `dto` param's ibGib properties.\n *\n * We do this because when we persist this space (and its settings\n * located in `data`), we do not save the actual class instantiation\n * but just the ibgib properties. Use this factory method to\n * create a new space instance and rehydrate from that saved dto.\n *\n * ## notes\n *\n * * DTO stands for data transfer object.\n *\n * @param dto space ibGib dto that we're going to load from\n * @returns newly created space built upon `dto`\n */\n static async createFromDto<\n TData extends NodeFilesystemSpaceData_V1 = NodeFilesystemSpaceData_V1,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n >(dto: IbGib_V1<TData, TRel8ns>): Promise<NodeFilesystemSpace_V1<TData, TRel8ns>> {\n const lc = `[${FilesystemSpace_V1.name}][${this.createFromDto.name}]`;\n if (logalot) { console.log(`${lc}`); }\n const space = new NodeFilesystemSpace_V1<TData, TRel8ns>();\n await space.initialized;\n await space.loadIbGibDto(dto);\n return space;\n }\n\n protected async validateWitnessArg(arg: NodeFilesystemSpaceOptionsIbGib): Promise<string[]> {\n const lc = `${this.lc}[${this.validateWitnessArg.name}]`;\n let errors: string[] = [];\n try {\n errors = (await super.validateWitnessArg(arg)) || [];\n if (arg.data?.cmd === 'put' && (arg.ibGibs || []).length === 0) {\n errors.push(`when \"put\" cmd is called, ibGibs required.`);\n }\n if (arg.data?.cmd === 'get' && (arg.data?.ibGibAddrs || []).length === 0) {\n errors.push(`when \"get\" cmd is called, ibGibAddrs required.`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (errors?.length > 0) { console.error(`${lc} errors: ${errors}`); }\n }\n\n return errors;\n }\n\n /**\n * Initializes to default space values.\n */\n protected async initialize(): Promise<void> {\n const lc = `${this.lc}[${this.initialize.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!this.data) {\n this.data = clone(DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1);\n this.data = this.data!; // why does ts compiler need this?\n }\n // if (!this.data?.classname) { this.data!.classname = NodeFilesystemSpace_V1.name }\n if (this.data!.classname !== this.classname) {\n if (this.data.classname) {\n // only warn if the consumer has explicitly set a different classname\n debugger; // how are we hitting this in space-gib server init\n console.warn(`${lc} initializer tried to init this data with this.data.classname (${this.data.classname}) !== ${this.classname}. overriding this to be ${this.classname}. (W: 0f53162c43a440c2a790c19dd223c6b6)`);\n }\n this.data!.classname = this.classname; // always set?\n }\n if (!this.data.baseDir) { this.data.baseDir = IBGIB_BASE_DIR; }\n if (!this.data.encoding) { this.data.encoding = IBGIB_ENCODING; }\n if (!this.data.baseSubPath) { this.data.baseSubPath = IBGIB_BASE_SUBPATH; }\n if (!this.data.spaceSubPath) { this.data.spaceSubPath = IBGIB_SPACE_SUBPATH_DEFAULT; }\n if (!this.data.ibgibsSubPath) { this.data.ibgibsSubPath = IBGIB_IBGIBS_SUBPATH; }\n if (!this.data.metaSubPath) { this.data.metaSubPath = IBGIB_META_SUBPATH; }\n if (!this.data.binSubPath) { this.data.binSubPath = IBGIB_BIN_SUBPATH; }\n if (!this.data.dnaSubPath) { this.data.dnaSubPath = IBGIB_DNA_SUBPATH; }\n\n // do nothing, allow falsy\n if (this.data.longSubPath === undefined) { this.data.longSubPath = IBGIB_LONG_SUBPATH; }\n if (this.data.longPathLength === undefined) { this.data.longPathLength = DEFAULT_LONG_PATH_LENGTH; }\n if (this.data.mitigateLongPaths === undefined) { this.data.mitigateLongPaths = true; }\n\n this.ib = getSpaceIb({ space: this, classname: this.data!.classname });\n\n this.gib = await getGib({ ibGib: this });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async putFile({\n ibGib,\n isDna,\n }: PutIbGibFileOpts): Promise<PutIbGibFileResult> {\n const lc = `${this.lc}[${this.putFile.name}]`;\n\n let result: PutIbGibFileResult = {};\n\n try {\n if (!ibGib) { throw new Error(`ibGib required. (E: b019eedc22094687a83dca8f7a98ba35)`) };\n\n const thisData = this.data!;\n // await this.ensureAllDirsExist();\n let path: string = \"\";\n let data: any = \"\";\n\n const addr = getIbGibAddr({ ibGib });\n const isBin = isBinary({ addr });\n path = await this.buildPath({\n addr, isDna: isDna ?? false, isBin, ensureMetaStonePaths: true,\n });\n await this.ensureDirsImpl([pathUtils.dirname(path)]);\n\n let fullPath = pathUtils.join(thisData.baseDir, path);\n\n if (logalot) { console.log(`${lc} fullPath: ${fullPath} (I: 2441a896f7e6418db57c0341d5c65ef2)`); }\n if (logalot) { console.log(`${lc} path: ${path}, directory: ${thisData.baseDir}, thisData.encoding: ${thisData.encoding} (I: d4440ececbe6c859f8fcf6d7ece12522)`); }\n\n\n let encoding: string | undefined;\n\n if (!isBin) {\n // not binary - most ibgibs will not be bins.\n\n // we only want to persist the ibGib protocol properties (not\n // any functions or other properties that might exist on the\n // incoming ibGib arg)\n const bareIbGib = toDto({ ibGib })\n data = JSON.stringify(bareIbGib);\n\n encoding = thisData.encoding || 'utf8';\n await writeFile(fullPath, data, encoding as BufferEncoding);\n } else {\n // binary\n const binIbGib = ibGib as BinIbGib_V1;\n data = binIbGib.data;\n if (!data) { throw new Error(`(UNEXPECTED) binIbGib.data falsy? I'm trying to have data always populated for bin ibgibs even if it is an empty Uint8Array. (E: 8c9c3650ec97792b1913754ed0877824)`); }\n\n // if (!Buffer.isBuffer(data)) {\n // debugger; // checking to see if !Buffer.isBuffer(data) fails for Uint8Array\n // throw new Error(`(UNEXPECTED) !Buffer.isBuffer(data)? I'm trying to have binIbGib.data always populated and it should be a Buffer. (E: 179c97da10ac082b77376c0db9077d24)`);\n // }\n // encoding = parseBinIb({ addr }).binEncoding ?? undefined\n\n // write bins directly as buffers\n // const dataBuffer = Buffer.from(data);\n await writeFile(fullPath, data);\n }\n\n result.success = true;\n } catch (error) {\n const errorMsg = `${lc} ${extractErrorMsg(error)}`;\n console.error(errorMsg);\n result.errorMsg = errorMsg;\n }\n\n return result;\n }\n\n protected async deleteFile({\n addr,\n isDna,\n }: DeleteIbGibFileOpts): Promise<DeleteIbGibFilesResult> {\n const lc = `${this.lc}[${this.deleteFile.name}]`;\n\n const result: DeleteIbGibFilesResult = {};\n\n try {\n if (!addr) { throw new Error(`addr required. (E: 98ff4fb4067a4a8281e21756aca4bf82)`) };\n\n if (!this.data) { throw new Error(`this.data required (E: 27e1f5206d96d635e617f5ba69141423)`); }\n const data = this.data;\n let path: string = \"\";\n\n if (!isBinary({ addr })) {\n // regular ibGib\n path = await this.buildPath({\n addr, isDna: isDna ?? false, ensureMetaStonePaths: true,\n });\n } else {\n path = await this.buildPath({\n addr, isDna: false, isBin: true, ensureMetaStonePaths: false,\n });\n }\n if (logalot) { console.log(`${lc} path: ${path}, directory: ${data.baseDir}`); }\n const fullPath = pathUtils.join(this.data.baseDir, path);\n await rm(fullPath, { force: true });\n if (logalot) { console.log(`${lc} deleted. path: ${path}`); }\n result.success = true;\n } catch (error) {\n const errorMsg = `${lc} ${extractErrorMsg(error)}`;\n if (!errorMsg.includes('File does not exist')) {\n console.error(errorMsg);\n } else {\n if (logalot) { console.log(`${lc} attempted to delete non-existent file. ${errorMsg} (I: 8953b51a5f14960e5ea2e86f6c6a7622)`); }\n }\n result.errorMsg = errorMsg;\n }\n\n return result;\n }\n\n protected async getFile({\n addr,\n isDna,\n }: GetIbGibFileOpts): Promise<GetIbGibFileResult> {\n let lc = `${this.lc}[${this.getFile.name}(${addr})]`;\n\n const result: GetIbGibFileResult = {};\n try {\n if (logalot) { console.log(`${lc} starting... (I: f69b58063ff7cafaaab341e633002a23)`); }\n if (!addr) { throw new Error(`addr required`) };\n\n const data = this.data!;\n const { ib } = getIbAndGib({ ibGibAddr: addr });\n\n const addrIsBin = isBinary({ addr });\n const knownTransformIbs = ['fork', 'mut8', 'rel8', 'plan']; // hack/kluge here\n const addrMightBeDna =\n knownTransformIbs.some(x => x === ib || x.startsWith(ib + ' '));\n\n const pathsToLook: string[] = [];\n\n if (isDna || addrMightBeDna) {\n pathsToLook.push(await this.buildPath({\n addr, isDna: true, ensureMetaStonePaths: false\n }));\n } else if (addrIsBin) {\n pathsToLook.push(await this.buildPath({\n addr, isDna: false, isBin: true, ensureMetaStonePaths: false\n }));\n }\n\n // always look in the main location as a last resort\n pathsToLook.push(await this.buildPath({\n addr, isDna: false, ensureMetaStonePaths: false\n }));\n\n // ...(pretend shortened as well as an absolute last last resort)\n if (!isMetaStone({ addr })) {\n pathsToLook.push(await this.buildPath({\n addr, isDna: false, ensureMetaStonePaths: false,\n pretendItsALongPath: true,\n }));\n }\n\n // this is ugly atow (02/2024) because i'm struggling a bit of\n // changing bin ibgibs to actually support binaries. i apologize.\n\n if (!addrIsBin) {\n // non-bin ibGib(s) retrieved (most ibgibs are non-bin)\n let resRead: any = null;\n for (const tryPath of pathsToLook) {\n const x = await tryRead({ path: tryPath, directory: data.baseDir, encoding: data.encoding });\n if (x) { resRead = x; break; }\n }\n if (resRead) {\n result.ibGib = JSON.parse(resRead) as IbGib_V1;\n } else {\n if (logalot) { console.log(`${lc} paths not found: ${JSON.stringify(pathsToLook)} (I: 7fc6c550b1a047d8a14392185de1b06e)`); }\n // will return success since it's not really an error, but ibgib\n // will not be populated, indicating the addr was not found.\n }\n } else {\n // bin\n let resRead: FileDataInfo | null = null;\n let { binEncoding, binHash } = parseBinIb({ addr });\n if (binHash === '0') {\n // special case: if the binHash is 0, then it is an empty file.\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n result.ibGib = {\n ib,\n gib,\n data: new Uint8Array(0),\n // data: '',\n // rawData: Buffer.from([]),\n } as BinIbGib_V1;\n } else {\n for (const tryPath of pathsToLook) {\n const x = await tryRead_bin({\n path: tryPath, directory: data.baseDir, encoding: binEncoding ?? data.encoding,\n });\n if (x) { resRead = x; break; }\n }\n\n if (resRead) {\n // all bins are buffers\n const { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n const binIbGib: BinIbGib_V1 = {\n ib, gib, data: resRead.dataBuffer,\n // rawData: resRead.dataBuffer,\n }\n result.ibGib = binIbGib;\n } else {\n if (logalot) { console.log(`${lc} paths not found: ${JSON.stringify(pathsToLook)} (I: 6a3bd3b125619da7a944200b14e7e922)`); }\n // will return success since it's not really an error, but ibgib\n // will not be populated, indicating the addr was not found.\n }\n }\n }\n\n result.success = true;\n } catch (error) {\n const errorMsg = `${lc} ${extractErrorMsg(error)}`;\n console.error(errorMsg);\n result.errorMsg = errorMsg;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: 413374e48f0a3cb8fd25de0d82134123)`); }\n }\n\n return result;\n }\n\n protected async ensurePermissions(): Promise<boolean> {\n const lc = `${this.lc}[${this.ensurePermissions.name}]`;\n if (logalot) { console.log(`${lc} always returns true in base class (I: 0a036a097093c622167e40f81e03d923)`); }\n return true;\n }\n\n protected async ensureAllDirsExist(): Promise<void> {\n const lc = `${this.lc}[${this.ensureAllDirsExist.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f9f1bc18215fd591cf9dcaea4deaa323)`); }\n\n if (!this.data) { throw new Error(`this.data required (E: ccf51541c1d5714ddafb67a8c3289823)`); }\n if (!this.data.uuid) { throw new Error(`this.data.uuid required (E: 33691c4c97e2033bf13d2c2d26a8f823)`); }\n\n const data = this.data!;\n\n /** these are the paths we're ensuring exist. all ibgibs are stored here. */\n const paths = [\n data.baseSubPath, // = 'ibgib';\n data.baseSubPath + '/' + data.spaceSubPath,\n data.baseSubPath + '/' + data.spaceSubPath + '/' + data.ibgibsSubPath,\n data.baseSubPath + '/' + data.spaceSubPath + '/' + data.metaSubPath,\n data.baseSubPath + '/' + data.spaceSubPath + '/' + data.binSubPath,\n data.baseSubPath + '/' + data.spaceSubPath + '/' + data.dnaSubPath,\n ];\n\n if (data.mitigateLongPaths) {\n paths.push(data.baseSubPath + '/' + data.spaceSubPath + '/' + data.longSubPath);\n }\n\n await this.ensureDirsImpl(paths);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * actually executes the ensure functionality for given `paths`. If they\n * don't exist, then this tries to make the dirs.\n * @param paths to ensure exist.\n */\n protected async ensureDirsImpl(paths: string[]): Promise<void> {\n const lc = `${this.lc}[${this.ensureDirsImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ad355a80dafa5873ac8ef31bf1f27923)`); }\n if (paths.length === 0) {\n console.warn(`${lc} paths empty? returning early. (W: a089ab1c9c0a4275a49341fb9f4c01c1)`)\n return; /* <<<< returns early */\n }\n\n const directory = this.data!.baseDir;\n\n const getPathKey = (p: string) => { return directory.toString() + '/' + p; }\n\n let allExist = paths.every(p => this.pathExistsMap[getPathKey(p)]);\n if (allExist) {\n if (logalot) { console.log(`${lc} allExist (I: f14ad6db1d29e368c37c3117fee1cb22)`); }\n return; /* <<<< returns early */\n }\n\n const permitted = await this.ensurePermissions();\n if (!permitted) {\n console.error(`${lc} permission not granted.`);\n return; /* <<<< returns early */\n }\n\n for (let i = 0; i < paths.length; i++) {\n const path = paths[i];\n const lc2 = `${lc}[(path: ${path}, directory: ${directory})]`;\n const fullPath = pathUtils.join(directory, path);\n\n // check if we've already ensured for this path\n const pathExistsKey = getPathKey(path);\n let exists = this.pathExistsMap[pathExistsKey] || false;\n\n if (!exists) {\n // we've not checked this path (or it didn't exist)\n try {\n exists = existsSync(fullPath);\n this.pathExistsMap[pathExistsKey] = exists;\n } catch (error) {\n if (logalot) { console.log(`${lc2} Did not exist`); }\n }\n }\n\n if (!exists) {\n // try full path\n if (logalot) { console.log(`${lc2} creating...`); }\n try {\n mkdirSync(fullPath, { recursive: true });\n exists = existsSync(fullPath);\n if (logalot) { console.log(`${lc} exists: ${exists}`); }\n this.pathExistsMap[pathExistsKey] = exists;\n } catch (error) {\n if (logalot) { console.log(`${lc2} Error creating. Trying next`); }\n } finally {\n if (logalot) { console.log(`${lc2} complete.`); }\n }\n }\n }\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /** */\n protected async getMetaStoneAddrs({\n ibGibAddr,\n tjpGib,\n fnFilterIb,\n }: {\n /**\n * addr of ibGib for which we're getting the metastones.\n */\n ibGibAddr: IbGibAddr,\n /**\n * tjpGib of the metastone's target ibgib\n */\n tjpGib: Gib,\n fnFilterIb?: (ib: Ib) => boolean,\n }): Promise<string[]> {\n const lc = `${this.lc}[${this.getMetaStoneAddrs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 510ba658195aa0aed9b8836f616d7823)`); }\n\n // first build the path with the given tjpGib\n // debugger;\n let pathSansBaseDir = await this.buildPath({\n addr: ibGibAddr, ensureMetaStonePaths: false, isDna: false,\n addrIsForAMetaStone: true,\n });\n let fullPath = pathUtils.join(this.data!.baseDir, pathSansBaseDir);\n if (logalot) { console.log(`${lc} fullPath: ${fullPath} (I: 9fc7113d6c9649f9b25f227ddad57f69)`); }\n\n // the given ibgib's containing dir is the one that should contain\n // the metastones.\n let gibInfo = getGibInfo({ ibGibAddr });\n\n let containingDir = !!gibInfo.tjpGib ?\n pathUtils.dirname(pathUtils.join(fullPath, '..')) :\n pathUtils.dirname(fullPath);\n if (logalot) { console.log(`${lc} containingDir: ${containingDir} (I: 2780437a6778a4633f49d81ac26ab723)`); }\n\n // iterate through the files for metastones.\n const fnFilter = fnFilterIb ?\n (s: string) => s.startsWith(META_STONE_ATOM) && fnFilterIb(s) :\n (s: string) => s.startsWith(META_STONE_ATOM);\n let filenames: string[] = [];\n try {\n if (logalot) { console.log(`${lc} calling readdir(containingDir) (I: 682d129a44d1101a0a7c2be999921923)`); }\n filenames = await readdir(containingDir, {\n recursive: false,\n withFileTypes: false,\n });\n } catch (error) {\n let emsg = extractErrorMsg(error);\n if (!emsg.includes('ENOENT')) { // no such file or directory\n console.warn(`${lc} readdir error did not contain ENOENT...not sure what this is...maybe a different OS no dir exists emsg? Treating this as if dir does not exist. (W: cde1cab3f64c47559782da8da55ed48a)`);\n } else {\n if (logalot) { console.log(`${lc} readdir errors: ${extractErrorMsg(error)} (I: 62bd4ec398b86ca84f7b3866dd83c123)`); }\n }\n filenames = [];\n }\n if (filenames.length === 0) {\n if (logalot) { console.log(`${lc} filenames: [empty]. no metastones found. (I: da9fef3f2edde037ca1c340bc38b7723)`); }\n return []; /* <<<< returns early */\n }\n if (logalot) { console.log(`${lc} filenames: ${filenames} (I: cb2948540a031522d184b1611f914323)`); }\n\n /**\n * atow (11/2023) extensions are hard-coded to \".json\",\n */\n const dotExt = '.json';\n const dotExtLength = 5;\n const metaStoneAddrs = filenames\n .filter(x => {\n // some filenames may be adjusted and not the full ibs.\n // however, the metastones are never shortened (atow\n // 11/2023), so those that don't have the delimiter will be\n // stored in ibIsh but they should get filtered out.\n const [ibIsh, gibPlusExt] = x.split(IBGIB_DELIMITER);\n return !!gibPlusExt?.endsWith(dotExt) && fnFilter(ibIsh);\n }).map(addrPlusExt => {\n // strip the extension\n return addrPlusExt.substring(0, addrPlusExt.length - dotExtLength);\n }).filter(metaStoneAddr => {\n // atow (11/2023) I'm not sure what other metastones are\n // going to be in this dir, so I'm saying it has to\n // explicitly contain the tjpGib.\n return isMetaStone({ addr: metaStoneAddr }) && metaStoneAddr.includes(tjpGib);\n });\n\n if (logalot) { console.log(`${lc} filtered/mapped filenames -> metaStoneAddrs: ${metaStoneAddrs} (I: ed062833a65730c04c7f9523e31a5a23)`); }\n\n // do some basic validation\n // throw (which could cripple in the future...), or silent fail\n // (which could lead to corrupt data)... hmm...going to throw for\n // now.\n for (let i = 0; i < metaStoneAddrs.length; i++) {\n const metaStoneAddr = metaStoneAddrs[i];\n let basicErrors = validateIbGibAddr({ addr: metaStoneAddr });\n if ((basicErrors ?? []).length > 0) {\n throw new Error(`(UNEXPECTED) invalid metastone found? metaStoneAddr (${metaStoneAddr}) had basic validation errors: ${basicErrors!.join('|')} (E: 318c164fc2014c036c91b179c8d7f623)`);\n }\n const { ib } = getIbAndGib({ ibGibAddr: metaStoneAddr });\n let metaStoneErrors = validateCommonMetaStoneIb({ ib });\n if (metaStoneErrors.length > 0) {\n throw new Error(`(UNEXPECTED) metaStoneIb had validation errors? metaStoneErrors: ${metaStoneErrors.join('|')} (E: 5a07b4dcd817f72a1a70e4b2d18f7323)`);\n }\n }\n\n // all good, return 'em!\n if (logalot) { console.log(`${lc} returning metaStoneAddrs: ${metaStoneAddrs} (I: c235e1005d02a53219e032f8818e8223)`); }\n return metaStoneAddrs;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\nexport async function convertData({\n data,\n encoding,\n}: {\n data: string,\n encoding: any,\n}): Promise<any> {\n const lc = `[${convertData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 77ef782249fdc9588c5b5b810126cc24)`); }\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { IBGIB_SPACE_NAME_DEFAULT } from \"../space-constants.mjs\";\nimport { Directory, Encoding } from \"./filesystem-types.mjs\";\n\n/**\n * atow this is '.' (cwd)\n *\n * In original ionic space, this would be \"DOCUMENTS\" or similar.\n */\nexport const IBGIB_BASE_DIR: Directory = '.';\n/**\n * atow this is 'utf8'\n *\n * this stems from original ionic space default encoding.\n */\nexport const IBGIB_ENCODING: Encoding = 'utf8';\n/**\n * Base directory for all data of the app.\n */\nexport const IBGIB_BASE_SUBPATH = 'ibgib';\n/**\n * Default space that is also used for bootstrapping.\n *\n * The user should provide his/her own space name that will contain their data.\n * If a custom user space name is not provided, one should be auto-generated.\n *\n * ## notes\n *\n * * the leading 000's help to put the space earlier in alphabetized listing if viewing through an OS file viewer\n */\nexport const IBGIB_SPACE_SUBPATH_DEFAULT = `000_${IBGIB_SPACE_NAME_DEFAULT}`;\n/**\n * Subpath for \"normal\" ibgibs (non-meta, non-dna, non-binary, etc.).\n */\nexport const IBGIB_IBGIBS_SUBPATH = 'ibgibs';\n/**\n * should contain special-use ibgibs to the application.\n *\n * Use case:\n * Because some special ibgibs will be changed frequently,\n * e.g. settings, a separate folder will be useful.\n */\nexport const IBGIB_META_SUBPATH = 'meta';\n/**\n * Path for storing the dna for ibgibs.\n *\n * bins will be stored without hyphens in the format:\n * [hash].[ext]\n *\n * @example\n * 641575866a7c42bda89f58de5cd1c3aa.jpg\n */\nexport const IBGIB_BIN_SUBPATH = 'bin';\n/**\n * Path for storing the dna for ibgibs.\n *\n * ## notes\n *\n * eventually, these should most likely be stored in \"colder\"\n * storage, like compressed, low-priority.\n */\nexport const IBGIB_DNA_SUBPATH = 'dna';\n/**\n * store long paths here.\n *\n * WARNING: short name used here specifically because we're trying to mitigate\n * existing technical debt outside of the the ibgib codebase. otherwise, this\n * would be much more descriptive. please don't use non-descriptive short names\n * like this in ibgib code unless it's extremely justified.\n */\nexport const IBGIB_LONG_SUBPATH = 'l';\n\n/**\n * Yep, this one starts with default instead of ending with it.\n */\nexport const DEFAULT_FILESYSTEM_SPACE_DESCRIPTION = `This is a filesystem space. The ibgib data contains settings for the space itself, and the witness ibgib object interfaces with a back end that is hierarchical like a filesystem. Descend from this class if you're working with a similar space.`;\n\n/**\n * when deciding what a long path length is, this is the constant used.\n *\n * this is used in help mitigating some OSs path limits of 255.\n *\n * ## notes\n *\n * i have this well below the 255 limit on some OSs. probably too defensive.\n */\nexport const DEFAULT_LONG_PATH_LENGTH = 240;\n\n/**\n * used when building paths\n */\nexport const DEFAULT_PATH_SEPARATOR = '/';\n\n/**\n * want to get some more metadata past the initial atom(s) and 32 sounds like a\n * decent compromise of staying relatively short and doing this.\n */\nexport const ARBITRARY_IB_SUBSTRING_LENGTH_FOR_MITIGATE_LONG_PATH = 32;\n", "import { clone, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1, IbGibRel8ns_V1, sha256v1, } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { validateGib, validateIb, validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport { WitnessData_V1, Witness_V1, } from './witness-types.mjs';\nimport { ErrorIbGib_V1 } from '../common/error/error-types.mjs';\nimport { toDto } from '../common/other/ibgib-helper.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\nexport abstract class WitnessBase_V1<\n TOptionsData extends any,\n TOptionsRel8ns extends IbGibRel8ns_V1,\n TOptionsIbGib extends IbGib_V1<TOptionsData, TOptionsRel8ns>,\n TResultData extends any,\n TResultRel8ns extends IbGibRel8ns_V1,\n TResultIbGib extends IbGib_V1<TResultData, TResultRel8ns> | ErrorIbGib_V1,\n TData extends WitnessData_V1 = any,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n>\n implements Witness_V1<\n TOptionsData, TOptionsRel8ns, TOptionsIbGib, // options arg\n TResultData, TResultRel8ns, TResultIbGib, // result\n TData, TRel8ns // this witness itself\n > {\n\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${WitnessBase_V1.name}]`;\n\n /**\n * Optional arg for verbose logging.\n */\n protected set trace(value: boolean) {\n const lc = `${this.lc}[set trace]`;\n if (value === (this.data?.trace || false)) { return; }\n if (this.data) {\n this.data.trace = value;\n delete this.gib; // gib is invalid now\n } else {\n console.warn(`${lc} data is falsy. Can't set.`);\n }\n }\n protected get trace(): boolean { return this.data?.trace ?? false; }\n\n /**\n * Optional configuration for `witness` call.\n * If true, then this space will catch any error that propagates up\n * from the `witnessImpl` function.\n *\n * ## notes\n *\n * Descendants of Witness who don't override the base `witness` function\n * (but rather override `witnessImpl` as expected) don't need to check\n * for this explicitly, since it is referenced in the base `witness`\n * function implementation.\n */\n protected set catchAllErrors(value: boolean) {\n const lc = `${this.lc}[set catchAllErrors]`;\n if (value === this.data?.catchAllErrors) { return; }\n if (this.data) {\n this.data.catchAllErrors = value;\n delete this.gib;\n } else {\n console.error(`${lc} data is falsy. Can't set value.`);\n }\n }\n protected get catchAllErrors(): boolean {\n const lc = `${this.lc}[catchAllErrors]`;\n const result = this.data?.catchAllErrors || false;\n if (logalot || this.trace) { console.log(`${lc} result: ${result}`) }\n return result;\n }\n\n // #region IbGib interface fields: ib, gib, data, rel8ns\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n ib: string = '';\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n gib: string | undefined;\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n data: TData | undefined;\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n rel8ns: TRel8ns | undefined;\n\n // #endregion IbGib interface fields: ib, gib, data, rel8ns\n\n /**\n * await this to ensure the witness is ready.\n *\n * This is called in the base `Witness.witness` function before `witnessImpl`.\n */\n initialized: Promise<void> | undefined;\n\n constructor(initialData?: TData, initialRel8ns?: TRel8ns) {\n if (initialData) { this.data = initialData; }\n if (initialRel8ns) { this.rel8ns = initialRel8ns; }\n this.initialized = this.initialize();\n }\n\n /**\n * by default, simply returns true atow in base class.\n * override this to perform code before any other code is executed.\n */\n protected initialize(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Creates a data transfer object (dto) snapshot out of this\n * witness' `ib`, `gib`, `data` and `rel8ns` properties.\n *\n * I say \"snapshot\" because this copies each property\n * (`ib`, `gib`, `data`, `rel8ns`).\n *\n * ## thoughts\n *\n * Witness classes need to be able to persist their ibgib\n * just as regular data. But witnesses have the additional\n * layer of behavior (e.g. the `witness` function) that\n * will not persist (until we get more integrated version control\n * types of functionality in ibgib).\n *\n * @returns dto ibgib object with just clones of this.ib/gib/data/rel8ns props.\n *\n * @see {loadIbGibDto}\n */\n toIbGibDto(): IbGib_V1<TData, TRel8ns> {\n return toDto({ ibGib: this });\n // const lc = `${this.lc}[${this.toIbGibDto.name}]`;\n // if (!this.ib) { console.warn(`${lc} this.ib is falsy. (W: 60162e3ab42941e9a68cd6adc8d23387)`); }\n // if (!this.gib) { console.warn(`${lc} this.gib is falsy. (W: 61dc535639dc410d874635013fce5b8a)`); }\n\n // let dtoIbGib: IbGib_V1<TData, TRel8ns> = { ib: (this.ib || '').slice() };\n // if (this.gib) { dtoIbGib.gib = this.gib.slice(); };\n // if (this.data) { dtoIbGib.data = clone(this.data); }\n // if (this.rel8ns) { dtoIbGib.rel8ns = clone(this.rel8ns); }\n\n // return dtoIbGib;\n }\n\n /**\n * (Re)hydrates this witness class with the ibgib information from the dto.\n *\n * ## notes\n *\n * * You can extend this function for witness-specific behavior when loading.\n *\n * @param dto ib, gib, data & rel8ns to load for this witness ibgib instance.\n *\n * @see {toIbGibDto}\n */\n loadIbGibDto(dto: IbGib_V1<TData, TRel8ns>): Promise<void> {\n const lc = `${this.lc}[${this.loadIbGibDto.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!dto.ib) { console.warn(`${lc} dto.ib is falsy.`); }\n if (!dto.gib) { console.warn(`${lc} dto.gib is falsy.`); }\n\n this.ib = clone(dto.ib);\n this.gib = clone(dto.gib);\n if (dto.data) {\n this.data = clone(dto.data);\n } else {\n delete this.data;\n }\n if (dto.rel8ns) { this.rel8ns = clone(dto.rel8ns); } else { delete this.rel8ns; }\n\n return Promise.resolve();\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * The primary function of a witness is...well... to witness things.\n *\n * So this is the base implementation that includes validation\n * plumbing, tracing, error checking/catching - all depending\n * on witness configuration.\n *\n *\n * ## usage\n *\n * Only override this function if you really want custom handling of\n * the plumbing. Instead override `witnessImpl`.\n *\n * {@see validateThis}\n * {@see validateWitnessArg}\n *\n * @param arg\n * @returns\n */\n async witness(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.witness.name}]`;\n try {\n await this.initialized;\n if (!this.gib) { this.gib = await sha256v1(this.toIbGibDto()); }\n const validationErrors_this = await this.validateThis();\n if (validationErrors_this?.length > 0) {\n for (const error of validationErrors_this) { console.error(`${lc} ${error}`); }\n throw new Error(`internal witness validation failed. See \\`WitnessBase_V1.validateThis\\` (E: 2b5f73cadbfa416ba189346f3c31cd0c)`);\n }\n const validationErrors_arg = await this.validateWitnessArg(arg);\n if (validationErrors_arg?.length > 0) {\n for (const error of validationErrors_arg) { console.error(`${lc} ${error}`); }\n throw new Error(`arg validation failed. See \\`WitnessBase_V1.validateWitnessArg\\` (E: 51531a1d928a485e8ffc277145ec44e9)`);\n }\n if (logalot || this.trace) { console.log(`${lc} addr: ${getIbGibAddr(arg)}`); }\n if (logalot) { console.log(`${lc} addr: ${getIbGibAddr(arg)} (I: f4cf13a44c4e4fc3903f14018e616c64)`); }\n const result = await this.witnessImpl(arg);\n\n // persist the arg and result if we're configured to do so it is up\n // to the implementation whether or not to throw on this.\n if (this.data?.persistOptsAndResultIbGibs) {\n await this.persistOptsAndResultIbGibs({ arg, result });\n }\n\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message || 'unknown error (E: 3e22bea4c7fb4668bf13d7146b927869)'}`);\n if (!this.catchAllErrors) {\n throw error;\n } else {\n return; // undefined\n }\n }\n }\n protected abstract witnessImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined>;\n\n /**\n * Validate the incoming arg.\n *\n * Override this in descending classes per use case.\n */\n protected async validateWitnessArg(arg: TOptionsIbGib): Promise<string[]> {\n const lc = `${this.lc}[${this.validateWitnessArg.name}]`;\n try {\n const errors: string[] = [];\n if (!arg) { errors.push(`arg required (E: a222db3b668e4bb09cfd82e75c07bfa6)`); }\n\n const ibErrors = validateIb({ ib: arg?.ib });\n if (ibErrors?.length ?? 0 > 0) { errors.push(`invalid arg.ib (E: 2ae362ef274d4c3bb9716800f2106d28) errors: ${ibErrors!.join('\\n')}`); }\n\n const gibErrors = validateGib({ gib: arg?.gib! });\n if (gibErrors?.length ?? 0 > 0) { errors.push(`invalid arg.gib (E: 73be275058084d768a39299337f2ce34) errors: ${gibErrors!.join('\\n')}`); }\n\n const intrinsicErrors = await validateIbGibIntrinsically({ ibGib: arg as IbGib_V1<any> });\n if (intrinsicErrors?.length ?? 0 > 0) {\n errors.push(`arg ibgib invalid intrinsically (E: 73be275058084d768a39299337f2ce34) errors: ${intrinsicErrors!.join('\\n')}`);\n } else if (!this.data?.allowPrimitiveArgs) {\n // further check to see if primitive\n const gibInfo = getGibInfo({ gib: arg.gib });\n if (gibInfo.isPrimitive) { errors.push(`arg is primitive (i.e. gib === \"gib\") and witness.data.allowPrimitiveArgs is falsy. (E: d0aa3d7ad4f54b01bd0023300d15ecd9)`) }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Validate this witness object, checking its own `data` and `rel8ns`, and\n * possibly other state.\n *\n * ## notes\n *\n * ATOW base implementation of this just checks for non-falsy\n * `this.ib` and `this.gib`\n */\n protected async validateThis(): Promise<string[]> {\n const lc = `${this.lc}[${this.validateThis.name}]`;\n const errors: string[] = [];\n try {\n if (!this.ib) { errors.push(`this.ib is falsy.`); }\n if (!this.gib) { errors.push(`this.gib is falsy.`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n return errors;\n }\n\n /**\n * Empty implementation in this base class.\n *\n * @see {@link WitnessData_V1.persistOptsAndResultIbGibs}\n */\n protected persistOptsAndResultIbGibs({\n arg,\n result\n }: {\n arg: TOptionsIbGib,\n result: TResultIbGib | undefined\n }): Promise<void> {\n const lc = `${this.lc}[${this.persistOptsAndResultIbGibs.name}]`;\n console.warn(`${lc} not implemented in this base class. Override this in descendent class. (W: 087514e851704322a4ec8069a73ce944)`);\n return Promise.resolve();\n }\n\n}\n\nexport type WitnessBaseAny = WitnessBase_V1<any, any, IbGib_V1, any, any, IbGib_V1, any, any>;\n", "import { delay, extractErrorMsg, pretty, unique } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGibAddr, TjpIbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { validateIbGibAddr } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport {\n GIB, IbGib_V1,\n isPrimitive,\n IBGIB_DELIMITER,\n} from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { getFromSpace, getLatestAddrs } from '../../witness/space/space-helper.mjs';\nimport { getTimelinesGroupedByTjp, toDto } from './ibgib-helper.mjs';\nimport { IbGibSpaceAny } from '../../witness/space/space-base-v1.mjs';\nimport { FlatIbGibGraph } from './graph-types.mjs';\n\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Options when getting dependency graph for ibGib(s).\n *\n * Note that this is used both in local and outer space contexts.\n * When you want to default to the local user space in the local context,\n * i.e. in `IbgibsService` atow, pass in `null` for {@link space}.\n */\nexport interface GetGraphOptions {\n /**\n * source ibGib to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGib?: IbGib_V1,\n /**\n * source ibGibs to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGibs?: IbGib_V1[],\n /**\n * source ibGib address to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGibAddr?: IbGibAddr,\n /**\n * source ibGib addresses to grab dependencies of.\n *\n * caller can pass in `ibGib` or `ibGibs` or `ibGibAddr` or `ibGibAddrs`.\n */\n ibGibAddrs?: IbGibAddr[],\n /**\n * If true, for each timeline in each \"frozen\" ibgib graph we will get the\n * latest address in the timeline and recheck rel8d ibgibs for newly\n * added timeline branches.\n *\n * If false, this will only look in the past for each rel8d ibgib.\n *\n * ## notes\n *\n * Say you have a source ibgib with a comment \"child\" (relative to our\n * source ibgib). Now say you add an ibgib to that child comment. The rel8d\n * addr in the source ibgib will still point to the child comment's initial\n * addr - before it was changed by adding its own \"child\" (\"grandchild\" to\n * the source). So if you get a live dependency graph on the parent, it will\n * come across the child's timeline and get the latest for that timeline\n * (and associated ibgibs like the child's dna transforms that add the\n * grandchild). This will include the grandchild. If it's not a live graph,\n * then the parent will only have the child and will exclude the grandchild.\n */\n live?: boolean,\n /**\n * object that will be populated through recursive calls to this function.\n *\n * First caller of this function should not provide this and I'm not atow\n * coding a separate implementation function to ensure this.\n *\n * @see {@link skipAddrs}\n */\n gotten?: { [addr: string]: IbGib_V1 },\n /**\n * used when doing {@link live} dependency graph gets. Same use as\n * {@link gotten}, but with regards to timelines.\n */\n tjpAddrsAlreadyAnalyzed?: TjpIbGibAddr[],\n /**\n * List of ibgib addresses to skip not retrive in the dependency graph.\n *\n * This will also skip any ibgib addresses that would have occurred in the\n * past of these ibgibs, as when skipping an ibgib, you are also skipping\n * its dependencies implicitly as well (unless those others are related via\n * another ibgib that is not skipped of course).\n *\n * ## driving use case\n *\n * We don't want to get ibgibs that we already have, and this is cleaner\n * than pre-populating the `gotten` parameter for double-duty. That property\n * should be strictly used within this call recursively.\n *\n * @see {@link gotten}\n */\n skipAddrs?: IbGibAddr[],\n /**\n * Skip these particular rel8n names.\n *\n * ## driving intent\n *\n * I'm adding this to be able to skip getting dna ibgibs.\n *\n * ## see also\n *\n * @see {@link onlyRel8nNames} for whitelist of rel8n names for traversal\n */\n skipRel8nNames?: string[],\n /**\n * whitelist of rel8nNames to traverse.\n *\n * ## see also\n *\n * @see {@link skipRel8nNames} for a blacklist of rel8n names for traversal\n */\n onlyRel8nNames?: string[],\n /**\n * If not found when getting dependency graph, do we retry? This is the\n * max number of retries.\n */\n maxRetries?: number,\n /**\n * If provided and {@link maxRetries} is non-zero, the next retry will be\n * delayed this amount of time if one or more addrs are not found.\n */\n msBetweenRetries?: number,\n /**\n * Space within which we should be looking for ibGibs.\n *\n * ## NOTE on providing space vs local user space\n *\n * I'm reusing this interface for both generic space function and ibgib service\n * function, which has an implicit default space of the local user space if this\n * is falsy. So just pass in `null` if you are using this with ibgibs service and\n * want it to default to the local user space.\n */\n space: IbGibSpaceAny | null,\n /**\n * If supplied, will make intermittent calls to console.timeLog using this name.\n */\n timeLogName?: string,\n /**\n * When getting the live dependency graph, this is used so we don't\n * duplicate work in recursive calls.\n *\n * IOW, in the first run of{@link getGraphProjection_Live}, we call\n * getLatestAddrs which maps some addrs to the latest addrs in the space. So\n * we now have a reference to the latest and if we need to call the function\n * {@link getGraphProjection_Live} recursively, then we can provide this\n * info to reduce unnecessary computation.\n */\n mapTjpAddrToLatestAddrsInSpace?: { [tjpAddr: string]: IbGibAddr }\n}\n\nexport type GetGraphResult = FlatIbGibGraph;\n\nexport interface GetGraphProjectionOptions extends GetGraphOptions {\n // /**\n // * max depth away from source ibgibs to traverse\n // */\n // depth?: number;\n}\n\nexport interface GetDependencyGraphOptions extends GetGraphProjectionOptions {\n // depth?: undefined;\n}\n\n/**\n *\n * @returns dependency graph, live or non-live depending on {@link GetDependencyGraphOptions}\n *\n * Getting a `live` dependency graph means that we will be looking in the given\n * @see {@link GetDependencyGraphOptions.space} for updates to ibGibs' timelines\n * (those ibGibs that have timelines/tjps). This is more costly computationally\n * in the short-term, but often cheaper in the long-term.\n */\nexport async function getDependencyGraph({\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n}: GetGraphProjectionOptions): Promise<GetGraphResult> {\n const lc = `[${getDependencyGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c2a4426c22e849611ca0cedabe683a22)`); }\n\n const graph = await getGraphProjection({\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n });\n\n Object.values(graph).filter(ibGib => ibGib.ib.startsWith('comment ')).forEach(ibGib => { console.table(ibGib); });\n if (logalot) {\n console.log(`${lc} graph size: ${Object.keys(graph).length} (I: c6cb5e7e1e2611d35b9006fac6503d22)`);\n const ibs =\n Object.values(graph).filter(ibGib => ibGib.ib.startsWith('comment ') || ibGib.ib.startsWith('pic '))\n .map(ibGib => ibGib.ib);\n unique(ibs).forEach(ib => console.log(ib));\n }\n return graph;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nasync function getGraphProjection_initializeOpts({\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n}: GetDependencyGraphOptions): Promise<GetDependencyGraphOptions> {\n const lc = `[${getGraphProjection_initializeOpts.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: bd6807477f679345df9dddefe0b4e922)`); }\n\n if (!space) { throw new Error(`space required. (E: 9f38166ab70340cb919174f8d26af909)`); }\n if (!ibGib && !ibGibAddr && (ibGibs ?? []).length === 0 && (ibGibAddrs ?? []).length === 0) {\n throw new Error(`either ibGib/s or ibGibAddr/s required. (E: b6d08699651f455697f0d05a41edb039)`);\n }\n\n skipRel8nNames = skipRel8nNames || [];\n // do NOT initialize onlyRel8nNames because we do logic based on falsy value\n skipAddrs = skipAddrs || [];\n gotten = gotten || {};\n tjpAddrsAlreadyAnalyzed = tjpAddrsAlreadyAnalyzed || [];\n\n // convert single args (ibGib, ibGibAddr) into the array args, filtering\n // out primitives that we don't want. The `filter` function creates the\n // copy here, so we won't mutate the incoming arrays. (The ibgibs and\n // addrs themselves are immutable).\n ibGibAddrs = (ibGibAddrs ?? [])\n .filter(x => !isPrimitive({ gib: getIbAndGib({ ibGibAddr: x }).gib })) // no primitives\n .filter(x => !skipAddrs!.includes(x));\n ibGibs =\n (ibGibs ?? [])\n .filter(x => !isPrimitive({ ibGib: x })) // no primitives\n .filter(x => !skipAddrs!.includes(getIbGibAddr({ ibGib: x })));\n // if we're passed in a single ibGib, add it to the ibGibs array because\n // we're going to work off of that.\n if (ibGib &&\n !isPrimitive({ ibGib }) &&\n !ibGibs.some(x => x.gib === ibGib.gib) &&\n !skipAddrs.includes(getIbGibAddr({ ibGib }))\n ) {\n ibGibs.push(ibGib);\n }\n // if we're passed in a single ibGibAddr, add it to the ibGibAddrs array because\n // we're going to work off of that.\n if (ibGibAddr &&\n !isPrimitive({ gib: getIbAndGib({ ibGibAddr }).gib }) &&\n !ibGibAddrs.includes(ibGibAddr) &&\n !skipAddrs.includes(ibGibAddr)\n ) {\n ibGibAddrs.push(ibGibAddr);\n }\n return {\n ibGib, ibGibs, ibGibAddr, ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n };\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nasync function getGraphProjection_getIbGibsInIbGibAddrs({\n ibGibs,\n ibGibAddrs,\n gotten,\n skipAddrs,\n maxRetries, msBetweenRetries,\n timeLogName,\n space,\n}: GetGraphProjectionOptions): Promise<IbGib_V1[]> {\n const lc = `[${getGraphProjection_getIbGibsInIbGibAddrs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 67b2be37ff24393fff56e229304da122)`); }\n\n /**\n * ibgibs that we'll return\n */\n const resIbGibs: IbGib_V1[] = [];\n ibGibs ??= [];\n ibGibAddrs ??= [];\n skipAddrs ??= [];\n gotten ??= {};\n\n const addrsToGetFromSpace: IbGibAddr[] = [];\n const gottenAddrs: IbGibAddr[] = Object.keys(gotten ?? {}); // compute once in this closure\n const incomingIbGibAddrs = ibGibs.map(x => getIbGibAddr({ ibGib: x }));\n // const noNeedAddrs = [...gottenAddrs, ...incomingIbGibAddrs, ...skipAddrs,];\n for (let i = 0; i < ibGibAddrs.length; i++) {\n const addr = ibGibAddrs[i];\n if (skipAddrs.includes(addr) || incomingIbGibAddrs.includes(addr)) {\n continue;\n } else if (gottenAddrs.includes(addr)) {\n // we've already gotten this addr previously and put it into the\n // gotten object, so we don't need to retrieve it from space\n resIbGibs.push(gotten[addr]);\n } else {\n // if (!noNeedAddrs.includes(ibGibAddrs[i])) {\n addrsToGetFromSpace.push(ibGibAddrs[i]);\n }\n }\n\n if (logalot) { console.log(`${lc}[analyze debugging] addrsToGetFromSpace (${addrsToGetFromSpace.length}):\\n${addrsToGetFromSpace.join('\\n')} (I: b45a2614184b48b694becfd377c789f5)`); }\n\n if (addrsToGetFromSpace.length > 0) {\n // get from space, with retries if applicable\n let addrsToGet = addrsToGetFromSpace.concat();\n let retryCount = 0;\n maxRetries = maxRetries ?? 0;\n while (retryCount <= maxRetries && addrsToGet.length > 0) {\n if (timeLogName && retryCount === 0) { console.timeLog(timeLogName, `${lc} FIRST try starting...`) }\n if (timeLogName && retryCount > 0) { console.timeLog(timeLogName, `${lc} RETRY starting...`) }\n // delay if applicable\n if (retryCount > 0 && msBetweenRetries) {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} delaying ${msBetweenRetries}ms for retry`); }\n if (logalot) { console.log(`${lc} retrying. addrsToGet (${addrsToGet.length}): ${addrsToGet} (I: 8460694cdd5518472680784c3b96a822)`); }\n await delay(msBetweenRetries);\n }\n\n // do the get\n if (timeLogName) { console.timeLog(timeLogName, `${lc} getFromSpace (${addrsToGet?.length}) starting...`); }\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? (E: aa9f657695717034b3581066932d7d23)`); }\n let resGetThese = await getFromSpace({ addrs: addrsToGet, space });\n if (timeLogName) { console.timeLog(timeLogName, `${lc} getFromSpace complete.`); }\n if (resGetThese.success && (resGetThese.ibGibs?.length ?? 0) > 0) {\n resGetThese.ibGibs!.forEach(x => resIbGibs.push(x));\n // resGetThese.ibGibs.forEach(x => ibGibs.push(x));\n const gottenAddrs = resGetThese.ibGibs!.map(x => getIbGibAddr({ ibGib: x }));\n if (gottenAddrs.length === addrsToGet.length) {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} got all.`) }\n // got them all, so we're done\n addrsToGet = [];\n break;\n } else {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} got some.`) }\n // got only some, prune addrsToGet for next retry (if any)\n addrsToGet = addrsToGet.filter(x => !gottenAddrs.includes(x));\n }\n } else {\n // failed, maybe partial maybe completely\n const gottenIbGibs: IbGib_V1[] = (resGetThese.rawResultIbGib as any).ibGibs ?? [];\n if (gottenIbGibs.length > 0) {\n // failed partial\n gottenIbGibs.forEach(x => resIbGibs.push(x));\n // resGetThese.ibGibs.forEach(x => ibGibs.push(x));\n const gottenAddrs = gottenIbGibs.map(x => getIbGibAddr({ ibGib: x }));\n if (timeLogName) { console.timeLog(timeLogName, `${lc} got some.`) }\n // got only some, prune addrsToGet for next retry (if any)\n addrsToGet = addrsToGet.filter(x => !gottenAddrs.includes(x));\n } else {\n // failed completely, addrsToGet stays the same\n if (timeLogName) { console.timeLog(timeLogName, `${lc} failed. addrs: ${addrsToGet?.join(',')}`) }\n }\n }\n retryCount++;\n }\n if (addrsToGet?.length > 0) {\n // console.dir(primaryKeysDebug);\n throw new Error(`unable to retrieve dependency ibgibs from space (ib: ${space?.ib}). addrsToGet: ${addrsToGet.join('\\n')} (E: 8413594b6c1b447988781cf3f3e1729d)`);\n // throw new Error(`unable to retrieve dependency ibgibs from space (ib: ${space?.ib}).\\n\\nThis is often because downloading failed due to the sync space's server getting temporarily overloaded, OR...it sometimes happens when an ibgib doesn't get fully published to the sync space in the first place.\\n\\nYou could retry immediately or later, but if the problem persists, then retry from the publishers end (have the publisher sync again). (E: 8413594b6c1b447988781cf3f3e1729d)`);\n }\n }\n\n return resIbGibs;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function getGraphProjection(opts: GetDependencyGraphOptions): Promise<GetGraphResult> {\n const lc = `[${getGraphProjection.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 70508d7a5c63eae1f22ae851b32b3d22)`); }\n\n if (!opts.ibGib && !opts.ibGibAddr && (opts.ibGibs ?? []).length === 0 && (opts.ibGibAddrs ?? []).length === 0) {\n // no ibgibs/addrs, return empty - don't throw\n return {} as GetGraphResult; /* <<<< returns early */\n }\n\n // ibGib and ibGibAddr get condensed into ibGibs and ibGibAddrs\n let {\n /*ibGib,*/ ibGibs, /*ibGibAddr,*/ ibGibAddrs,\n live,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n } = await getGraphProjection_initializeOpts(opts);\n\n if (timeLogName) { console.timeLog(timeLogName, `${lc} starting...`) }\n\n // retrieve ibgibs listed in incoming ibGibAddrs (if any) and put them\n // in our incoming ibGibs array\n if (ibGibAddrs?.length ?? 0 > 0) {\n const supplementalIbGibs = await getGraphProjection_getIbGibsInIbGibAddrs({\n ibGibs, ibGibAddrs,\n gotten,\n skipAddrs,\n maxRetries, msBetweenRetries,\n timeLogName,\n space,\n });\n ibGibs = ibGibs ?\n [...ibGibs, ...supplementalIbGibs] :\n [...supplementalIbGibs]\n }\n ibGibAddrs = ibGibs!.map(x => getIbGibAddr({ ibGib: x }));\n\n\n // at this point, there are two different strategies for diving deeper,\n // depending on if we are building a `live` graph or not.\n\n let commentIbs = unique(ibGibs!.map(x => x.ib).filter(x => x.startsWith('comment ')));\n if (logalot) { console.log(`${lc}[analyze debugging] ibGibs commentIbs: ${commentIbs.join('\\n')} (I: c89dc951315f746954f9bddbe8941122)`); }\n\n if (live) {\n return getGraphProjection_Live({\n ibGibs, ibGibAddrs,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space, timeLogName,\n mapTjpAddrToLatestAddrsInSpace,\n });\n } else {\n return getGraphProjection_NonLive({\n ibGibs, ibGibAddrs,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space, timeLogName,\n });\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n\n/**\n * Get the dependency graph for {@link ibGibAddr} since {@link latestCommonFrameAddr}.\n *\n * if ibGibAddr is A^5 and latestCommonFrameAddr is A^3, then this should\n * get all dependencies in A^5 dependency graph NOT ALREADY IN the A^3\n * graph.\n *\n * NOTE: The {@link live} param is for the delta graph itself. The graph\n * corresponding to {@link latestCommonFrameAddr} is always calculated live ===\n * false.\n */\nexport async function getDeltaDependencyGraph({\n ibGibAddr,\n latestCommonFrameAddr,\n live,\n space,\n}: {\n ibGibAddr: string;\n latestCommonFrameAddr: string;\n live: boolean,\n space: IbGibSpaceAny;\n}): Promise<FlatIbGibGraph> {\n const lc = `[${getDeltaDependencyGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5d225e56dc11e62cd83c5366ea288826)`); }\n\n if (ibGibAddr === latestCommonFrameAddr) {\n console.warn(`${lc} ibGibAddr === latestCommonFrameAddr. So the delta graph is empty. what are we doing here? (W: e0c8287ae6de8152bf36b6c73ca59a26)`);\n return {};\n }\n\n const dependencyGraph_lcf = await getDependencyGraph({\n ibGibAddr: latestCommonFrameAddr,\n live: false, // always get the smaller graph live === false!\n space,\n });\n const dependencyGraph_delta = await getDependencyGraph({\n ibGibAddr,\n live,\n skipAddrs: Object.keys(dependencyGraph_lcf),\n space,\n });\n\n return dependencyGraph_delta;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n *\n * live dependency graph searching requires a timeline-centric approach.\n * for each incoming ibGib, we must first determine if it has a\n * timeline. if it does, then we get the latest in that timeline and\n * get all ibgibs in that lineage only. we do NOT YET go through any\n * rel8d ibgibs that also have timelines\n *\n * what we can do is compile our list of ibGib addrs according to each\n * timeline and then call the nonlive version of the dependency graph.\n * but we must get the latest in the timeline, then get all associated\n * timelines and get the latest of those. Then we can call get\n * dependency graph on the non-live version, passing in all of those\n * latest ibgibs in the timelines (and everything we've gotten in the\n * interim so we don't waste time getting more).\n *\n * @see {@link getGraphProjection}\n * @see {@link getDependencyGraph}\n */\nasync function getGraphProjection_Live({\n ibGibs, ibGibAddrs,\n gotten, tjpAddrsAlreadyAnalyzed,\n mapTjpAddrToLatestAddrsInSpace,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n}: GetGraphProjectionOptions): Promise<GetGraphResult> {\n const lc = `[${getGraphProjection_Live.name}]`;\n try {\n mapTjpAddrToLatestAddrsInSpace = mapTjpAddrToLatestAddrsInSpace ?? {};\n tjpAddrsAlreadyAnalyzed = tjpAddrsAlreadyAnalyzed ?? [];\n\n // ibGibs contains the ones we explicitly are still working on getting\n // projections within, gotten are the ones we have completed. so we want\n // to get all of them together so we have a complete (up to this point)\n // picture of timelines, because we're looking for timelines that we\n // haven't yet analyzed\n let allIbGibsSoFar = { ...gotten };\n (ibGibs ?? []).forEach(x => allIbGibsSoFar[getIbGibAddr({ ibGib: x })] = x);\n const allKnownTimelinesAtThisPoint = getTimelinesGroupedByTjp({\n ibGibs: Object.values(allIbGibsSoFar),\n });\n if (logalot) { console.log(`${lc}[analyze debugging] timeline tjps(${Object.keys(allKnownTimelinesAtThisPoint).length}): ${Object.keys(allKnownTimelinesAtThisPoint)} (I: 509f04ac15ca08c5a3f0777b48934622)`); }\n\n const timelinesNotAnalyzed: { [addr: string]: IbGib_V1[] } = {};\n Object.keys(allKnownTimelinesAtThisPoint).forEach(tjpAddr => {\n if (!tjpAddrsAlreadyAnalyzed!.includes(tjpAddr)) {\n timelinesNotAnalyzed[tjpAddr] = allKnownTimelinesAtThisPoint[tjpAddr];\n }\n });\n if (logalot) { console.log(`${lc}[analyze debugging] timelinesNotAnalyzed: ${pretty(timelinesNotAnalyzed)} (I: a4b67d95fdd6b98d3241c0a7d0a93c22)`); }\n\n const mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed: { [tjpAddr: IbGibAddr]: IbGib_V1 } = {};\n /**\n * Convience mapping back from latest addr already gotten back to the tjp addr.\n * Convenience = not strictly necessary, but makes it easier later.\n */\n const mapLatestAddrAlreadyGottenToTjpAddr: { [latestAddrAlreadyGotten: IbGibAddr]: IbGibAddr } = {};\n\n Object.keys(allKnownTimelinesAtThisPoint)\n .filter(tjpAddr => !tjpAddrsAlreadyAnalyzed!.includes(tjpAddr))\n .forEach(tjpAddr => {\n const timeline = allKnownTimelinesAtThisPoint[tjpAddr];\n // add to the array we'll send below\n const latestIbGibAlreadyGotten = timeline[timeline.length - 1];\n mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed[tjpAddr] = latestIbGibAlreadyGotten;\n // add to mapping back from addr to tjpaddr for convenience below\n const latestAddrAlreadyGotten = getIbGibAddr({ ibGib: latestIbGibAlreadyGotten });\n mapLatestAddrAlreadyGottenToTjpAddr[latestAddrAlreadyGotten] = tjpAddr;\n });\n let countOfTimelinesNotYetGotten =\n Object.keys(mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed).length;\n\n if (countOfTimelinesNotYetGotten > 0) {\n // we have more timelines still to do. get the latest ibGib in each timeline,\n // add it, check for more timelines. But we may have already gotten a latestAddrsMap\n // in a previous call, so account for this.\n\n // query only latest ibgibs that we haven't already gotten AND whose\n // timelines we've not already analyzed, per\n // mapTjpAddrToLatestAddrsInSpace.\n /**\n * build this map of latest addr given -> latest addr in space (per timeline/tjp).\n */\n let latestAddrsMap: { [addr: string]: IbGibAddr | null } = {};\n Object.keys(mapTjpAddrToLatestAddrsInSpace)\n .filter(tjpAddr => !tjpAddrsAlreadyAnalyzed!.includes(tjpAddr))\n .forEach(tjpAddr => {\n const latestIbGibCorrespondingToTjpAddr =\n mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed[tjpAddr];\n if (latestIbGibCorrespondingToTjpAddr) {\n const latestAddrCorrespondingToTjpAddr =\n getIbGibAddr({ ibGib: latestIbGibCorrespondingToTjpAddr });\n latestAddrsMap[latestAddrCorrespondingToTjpAddr] = mapTjpAddrToLatestAddrsInSpace![tjpAddr];\n } else {\n console.error(`${lc} latestIbGibCorrespondingToTjpAddr is falsy`)\n }\n });\n if (logalot) { console.log(`${lc} latestAddrsMap *before* getLatestAddrs: ${pretty(latestAddrsMap)} (I: 427b4bb78595e9e521ecf2c5e5c80722)`); }\n /**\n * these are the ibgibs whose timelines we are aware of but haven't\n * explicitly queried for the latest in the space.\n */\n const ibGibsToQueryLatestAddrs =\n Object.values(mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed);\n\n /**\n * this is the result map of ibgibs whose timelines we are aware of\n * but hadn't explicitly queried for.\n */\n let queriedLatestAddrsMap: { [addr: string]: IbGibAddr | null } = {};\n if (ibGibsToQueryLatestAddrs.length > 0) {\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? (E: 8e878975e3561df9a8dc4c628b0abc23)`); }\n /** This is result with the map of the latest addrs in the space */\n const resLatestAddrsMapInEntireSpace = await getLatestAddrs({\n ibGibs: ibGibsToQueryLatestAddrs,\n space,\n });\n if (!resLatestAddrsMapInEntireSpace?.data?.latestAddrsMap) { throw new Error(`(UNEXPECTED) getLatestAddrs result latestAddrsMap falsy (E: 088caa1fc95fd3b079108ab63ef33422)`); }\n queriedLatestAddrsMap = resLatestAddrsMapInEntireSpace?.data?.latestAddrsMap;\n if (Object.keys(queriedLatestAddrsMap).length !== countOfTimelinesNotYetGotten) {\n // this happens when the space does not have the address, sometimes because of\n // not pushing the most recent changes to the sync space...hmmm\n throw new Error(`(UNEXPECTED) latestAddrsMap is not the same size as the incoming map (E: 666af512bbd44534983bb28ee8d43fed)`);\n }\n if (logalot) { console.log(`${lc} queriedLatestAddrsMap: ${pretty(queriedLatestAddrsMap)} (I: 7b39a5f7ce9e9d9fabae4be98ed44522)`); }\n latestAddrsMap = {\n ...queriedLatestAddrsMap,\n ...latestAddrsMap\n };\n }\n if (logalot) { console.log(`${lc} combined latestAddrsMap: ${pretty(latestAddrsMap)} (I: e3aedea63f29c5b06a79632f691aa522)`); }\n\n /**\n * these addrs are those whose timelines we did not yet have the latest.\n * this means that we will have to work off of these ibgibs.\n */\n const newerAddrsFound: IbGibAddr[] = [];\n const newerAddrFoundToTjpAddrMap: { [newerAddrFound: string]: IbGibAddr } = {}\n Object.values(mapTjpAddrToLatestIbGibInTimelineThatWeHaventAlreadyAnalyzed)\n .forEach(latestIbGibAlreadyGotten => {\n const latestAddrAlreadyGotten = getIbGibAddr({ ibGib: latestIbGibAlreadyGotten });\n const tjpAddr = mapLatestAddrAlreadyGottenToTjpAddr[latestAddrAlreadyGotten];\n const latestAddrInSpace = latestAddrsMap[latestAddrAlreadyGotten];\n if (!latestAddrInSpace) { throw new Error(`(UNEXPECTED) latestAddrInSpace not found in latestAddrsMap (E: 095d2b3f88e3e8a2c3e7d3de4c6d5622)`); }\n if (latestAddrInSpace === latestAddrAlreadyGotten) {\n // we've already got the latest for this timeline. This\n // means that we must have already at least queued all\n // timelines possible, so nothing else to do.\n if (logalot) { console.log(`${lc} analyzed ${tjpAddr}(I: afb7960900f04b8a87538f4c7bd903b7)`); }\n tjpAddrsAlreadyAnalyzed!.push(tjpAddr);\n } else {\n // there is a newer \"latest\" in this timeline that we\n // haven't gotten yet, so add that addr to the\n newerAddrsFound.push(latestAddrInSpace);\n newerAddrFoundToTjpAddrMap[latestAddrInSpace] = tjpAddr;\n }\n });\n\n let rel8dAddrsNotYetGotten: IbGibAddr[] = [];\n for (let i = 0; i < (ibGibs ?? []).length; i++) {\n const ibGib = ibGibs![i];\n const rel8ns = ibGib.rel8ns ?? {};\n const rel8nNames = Object.keys(rel8ns)\n .filter(x => !(skipRel8nNames ?? []).includes(x))\n .filter(x => onlyRel8nNames ? onlyRel8nNames.includes(x) : true);\n rel8nNames.forEach(rel8nName => {\n const rel8dAddrs = rel8ns[rel8nName] ?? [];\n rel8dAddrs.forEach(rel8dAddr => {\n // only add todo if we don't already have the ibgib\n\n if (!rel8dAddrsNotYetGotten.includes(rel8dAddr) &&\n !ibGibs!.some(x => getIbGibAddr({ ibGib: x }) === rel8dAddr)\n ) {\n rel8dAddrsNotYetGotten.push(rel8dAddr);\n }\n });\n });\n }\n ibGibAddrs = unique([...(ibGibAddrs ?? []), ...rel8dAddrsNotYetGotten, ...newerAddrsFound]);\n\n // if (newerAddrsFound.length === 0) {\n // there were no newer addrs found, necessitating that we have\n // no additional ibgibs that we don't know about.\n\n return await getGraphProjection({\n ibGibs, ibGibAddrs,\n gotten, tjpAddrsAlreadyAnalyzed,\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n live: true,\n mapTjpAddrToLatestAddrsInSpace,\n });\n // } else {\n // // #region old notes\n\n // // i don't know if i'll need these or if this algorithm is\n // // working correctly. atow (02/2024) it looks like it is\n // // working from initial testing in b2tfs ibgib testing.\n\n // // there are still newer ibgibs that must be included in the analysis., without yet\n // // going into the direct rel8ns of\n // // need to call recursively this _Live function, passing in\n // // the already computated latest map in mapTjpAddrToLatestAddrsInSpace\n // // I need to also adjust preceding code to use this map.\n // // Object.keys(queriedLatestAddrsMap).forEach(latestAddrNotGotten => {\n // // Object.keys(queriedLatestAddrsMap).forEach(tjpAddr => {\n // // const latestAddrNotGotten = queriedLatestAddrsMap[tjpAddr];\n // // // const tjpAddr = mapLatestAddrAlreadyGottenToTjpAddr[latestAddrNotGotten];\n // // mapTjpAddrToLatestAddrsInSpace![tjpAddr] = latestAddrNotGotten;\n // // if (queriedLatestAddrsMap[latestAddrNotGotten]) { ibGibAddrs!.push(); }\n // // });\n // // ibGibAddrs = unique(ibGibAddrs);\n // // // ibGibAddrs = unique([...ibGibAddrs, ...rel8dAddrsNotYetGotten]);\n // // #endregion old notes\n\n // return await getGraphProjection({\n // ibGibs, ibGibAddrs,\n // gotten, tjpAddrsAlreadyAnalyzed,\n // skipAddrs, skipRel8nNames, onlyRel8nNames,\n // maxRetries, msBetweenRetries,\n // space,\n // timeLogName,\n // live: true,\n // mapTjpAddrToLatestAddrsInSpace,\n // });\n // }\n } else {\n // we have no more timelines that we haven't already gotten, so we\n // can pass off to the non-live version\n if (!ibGibs) { ibGibs = []; }\n Object.values(gotten ?? {}).forEach(x => {\n const addr = getIbGibAddr({ ibGib: x });\n if (!ibGibs!.some(y => getIbGibAddr({ ibGib: x }) === addr)) {\n ibGibs!.push(x);\n }\n });\n return await getGraphProjection({ /* <<<< returns early */\n ibGibs, ibGibAddrs,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n live: false,\n });\n }\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n console.error(emsg);\n if (timeLogName) { console.timeLog(timeLogName, `${lc} error: ${emsg}`); }\n throw error;\n } finally {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} complete.`) }\n }\n}\n\n/**\n * NOT EXPORTED\n *\n * @see {@link getGraphProjection}\n * @see {@link getDependencyGraph}\n */\nasync function getGraphProjection_NonLive({\n ibGibs, ibGibAddrs,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n timeLogName,\n}: GetGraphProjectionOptions): Promise<GetGraphResult> {\n const lc = `[${getGraphProjection_NonLive.name}]`;\n try {\n // next, compile what could be a rather large list of rel8d ibgibAddrs\n // which must necessarily be in the past of the futuremost incoming\n // ibGib/ibGibAddr/s as rel8ns only work backwards (whereas tjp's can\n // refer to future timelines, the DAG substrate only looks backwards)\n const addrsWeDontHaveAlready_Rel8dAddrs: IbGibAddr[] = [];\n ibGibs ??= [];\n gotten ??= {};\n skipAddrs ??= [];\n skipRel8nNames ??= [];\n\n // so, we will iterate through all of our given and loaded ibGibs (not\n // the ones in gotten map though), look through all of their rel8ns, and\n // add any that haven't already been gotten\n if (timeLogName) { console.timeLog(timeLogName, `${lc} analyzing next step starting...`); }\n for (let i = 0; i < ibGibs.length; i++) {\n const ibGib = ibGibs[i];\n const ibGibAddr = getIbGibAddr({ ibGib });\n\n // do i need this?\n const { gib } = getIbAndGib({ ibGib });\n if (gib === GIB) { throw new Error(`cannot get dependency graph of primitive.`); }\n\n // ?\n // I believe I have this so we don't try to do this ibgib again on recursive call.\n // but should I be adding it at this point? hmm...\n if (!Object.keys(gotten).includes(ibGibAddr)) { gotten[ibGibAddr] = ibGib; }\n\n // iterate through rel8ns and compile list of ibgib addrs not yet gotten\n /** map of addr to validation errors array */\n const invalidAddrs: { [addr: string]: string[] } = {};\n const rel8ns = ibGib.rel8ns || {};\n let rel8nNames = (Object.keys(rel8ns) || []).filter(x => !skipRel8nNames!.includes(x));\n if (onlyRel8nNames) {\n rel8nNames = rel8nNames.filter(x => onlyRel8nNames.includes(x));\n }\n const gottenKeys = Object.keys(gotten);\n for (let i = 0; i < rel8nNames.length; i++) {\n const rel8nName = rel8nNames[i];\n const rel8dAddrs = rel8ns[rel8nName] ?? [];\n const falsyAddrs = rel8dAddrs.filter(addr =>\n addr === '' ||\n addr === undefined ||\n addr === null ||\n !addr.includes(IBGIB_DELIMITER)\n );\n if (falsyAddrs.length > 0) { console.warn(`${lc} (UNEXPECTED) has falsyAddrs: ${falsyAddrs} (W: da9505cb0a4db68a4aff7f279ad2d322)`); }\n const rel8dAddrsNotGottenYetThisRel8n =\n rel8dAddrs\n .filter(addr => !!addr)\n .filter(addr => !gottenKeys.includes(addr))\n .filter(addr => !skipAddrs!.includes(addr))\n .filter(addr => getIbAndGib({ ibGibAddr: addr }).gib !== GIB)\n .filter(addr => !addrsWeDontHaveAlready_Rel8dAddrs.includes(addr));\n rel8dAddrsNotGottenYetThisRel8n.forEach(rel8dAddr => {\n const validationErrors = validateIbGibAddr({ addr: rel8dAddr });\n if ((validationErrors || []).length === 0) {\n // valid addr. add it if we haven't gotten/queued it yet\n addrsWeDontHaveAlready_Rel8dAddrs.push(rel8dAddr);\n } else {\n // invalid address\n invalidAddrs[rel8dAddr] = validationErrors!;\n }\n });\n }\n\n if (Object.keys(invalidAddrs).length > 0) {\n throw new Error(`invalid addresses found in dependency graph. Errors (clipped to 1kB): ${JSON.stringify(invalidAddrs).substring(0, 1024)}`);\n }\n }\n if (timeLogName) { console.timeLog(timeLogName, `${lc} analyzing next step complete.`); }\n\n if (addrsWeDontHaveAlready_Rel8dAddrs.length > 0) {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} get addrsWeDontHaveAlready_Rel8dAddrs starting...`); }\n // execute the get on those addrs\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? (E: 0ce327cf5d521bd798340333460f3423)`); }\n const resGet = await getFromSpace({ addrs: addrsWeDontHaveAlready_Rel8dAddrs, space });\n if (timeLogName) { console.timeLog(timeLogName, `${lc} get addrsWeDontHaveAlready_Rel8dAddrs complete.`); }\n if (resGet.success) {\n if (resGet.ibGibs?.length === addrsWeDontHaveAlready_Rel8dAddrs.length) {\n if (logalot) { console.log(`${lc} got ALL of them (happy path)`); }\n resGet.ibGibs.forEach(x => gotten![getIbGibAddr({ ibGib: x })] = x);\n // return a recursive call for the newly-gotten ibgibs'\n // dependencies, passing in the now-larger accumulating\n // `gotten` map of ibgibs already processed.\n if (timeLogName) { console.timeLog(timeLogName, `${lc} call getGraphProjection recursively starting...`); }\n const result = await getGraphProjection({\n ibGibs: resGet.ibGibs,\n live: false,\n gotten, /* tjpAddrsAlreadyAnalyzed not used */\n skipAddrs, skipRel8nNames, onlyRel8nNames,\n maxRetries, msBetweenRetries,\n space,\n });\n if (timeLogName) { console.timeLog(timeLogName, `${lc} call getGraphProjection recursively complete.`); }\n return result; // <<<< returns early\n } else if ((resGet.ibGibs?.length ?? 0) > 0 && resGet.ibGibs!.length < addrsWeDontHaveAlready_Rel8dAddrs.length) {\n if (logalot) { console.warn(`${lc} got SOME of them (happy-ish path?). not sure what to do here... (W: e3458f61a1ae4979af9e6b18ac935c14)`); }\n throw new Error(`trouble getting dependency ibgibs (E: 8156bf65fd084ae4a4e8a0669db28b07)`);\n } else if ((resGet.ibGibs?.length ?? 0 > 0) && resGet.ibGibs!.length > addrsWeDontHaveAlready_Rel8dAddrs.length) {\n // got more than our original list? not a good space behavior...\n throw new Error(`(UNEXPECTED) got more ibGibs than addrs that we asked for. space not working properly. (E: 352219b3d18543bcbda957f2d60b78f3)`);\n } else {\n // didn't get any...hmm...\n throw new Error(`couldn't get dependency ibgibs from space. (E: 225f26b7d7f84911bb033753a062209b)`);\n }\n } else {\n // resGet.success falsy indicates an error in the space. If it wasn't found\n // then resGet.success would (should) still be truthy.\n throw new Error(`failure getting addrs in space ${space?.data?.name || '[no name?]'} (id: ${space?.data?.uuid || '[no uuid?]'}). (E: 60404e6e389249d9bbecf0039cd51878) addrs:\\n${addrsWeDontHaveAlready_Rel8dAddrs.join('\\n')} `);\n }\n } else {\n // no other rel8d addrs to get, so our job is done and the `gotten`\n // map of dependency ibgibs is complete (no need for another\n // recursive call).\n return gotten;\n }\n\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n console.error(emsg);\n if (timeLogName) { console.timeLog(timeLogName, `${lc} error: ${emsg}`); }\n throw error;\n } finally {\n if (timeLogName) { console.timeLog(timeLogName, `${lc} complete.`) }\n }\n}\n\n/**\n * Helper function to convert an array of {@link ibGibs} (or undefined) to a\n * {@link FlatIbGibGraph} ([addr] -> ibGib map).\n * @returns if ibGibs undefined returns undefined, else flat graph map\n */\nexport function toFlatGraph({ ibGibs }: { ibGibs: IbGib_V1[] | undefined }): FlatIbGibGraph | undefined {\n const lc = `[${toFlatGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 6019a812cff8597f79c12088e45cc226)`); }\n\n if (ibGibs) {\n const resGraph: FlatIbGibGraph = {};\n ibGibs.forEach(x => { resGraph[getIbGibAddr({ ibGib: x })] = x; })\n return resGraph;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * compare two graphs for \"equivalency\".\n *\n * The default just checks that sizes and addrs are the same.\n *\n * The more thorough check does the json strings of the values (as dtos).\n */\nexport function graphsAreEquivalent({\n graphA,\n graphB,\n slowButThorough,\n}: {\n graphA: FlatIbGibGraph,\n graphB: FlatIbGibGraph,\n /**\n * if true, will actually compare the dto strings of each ibgib in the graph\n */\n slowButThorough?: boolean,\n}): boolean {\n const lc = `[${graphsAreEquivalent.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e50a98b659189dece8b4ef581e4ad826)`); }\n\n const sameSize = Object.keys(graphA).length === Object.keys(graphB).length;\n if (!sameSize) {\n if (logalot) { console.log(`${lc} not the same size. false. (I: e1044e52421dbf7e067e0fe850ac6826)`); }\n return false; /* <<<< returns early */\n }\n\n for (const addr of Object.keys(graphA)) {\n if (!graphB[addr]) {\n if (logalot) { console.log(`${lc} addr (${addr}) in graphA not found in graphB (I: 264c68408378ce30b8f6a978f8b86926)`); }\n return false; /* <<<< returns early */\n }\n }\n\n if (slowButThorough) {\n // go back through and check for dto string equality (deep equality)\n for (const addr of Object.keys(graphA)) {\n const ibGibA = toDto({ ibGib: graphA[addr] });\n const jsonA = JSON.stringify(ibGibA);\n const ibGibB = toDto({ ibGib: graphB[addr] });\n const jsonB = JSON.stringify(ibGibB);\n if (jsonA !== jsonB) {\n if (logalot) { console.log(`${lc} jsonA !== jsonB for addr (${addr}) (I: 98ed9f58ac88dabba83f96582f725926)`); }\n return false; /* <<<< returns early */\n }\n }\n }\n\n return true;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}", "import { CLASSNAME_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Ib } from '@ibgib/ts-gib/dist/types.mjs';\nimport {\n IbGib_V1, IbGibRel8ns_V1, Factory_V1 as factory, sha256v1,\n} from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport { WITNESS_ARG_METADATA_STRING, WITNESS_RESULT_METADATA_STRING } from './witness-constants.mjs';\n\nimport { WitnessCmdData } from './witness-cmd/witness-cmd-types.mjs';\nimport { Witness, WitnessAny } from './witness-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Builds the ib for the witness arg ibgib.\n *\n * @returns ib that we'll use when creating a witness arg.\n */\nexport function getArgIb(ibMetadata: string | undefined): string {\n const lc = `[${getArgIb.name}]`;\n try {\n const ib = ibMetadata ?\n `${WITNESS_ARG_METADATA_STRING} ${ibMetadata}` :\n WITNESS_ARG_METADATA_STRING;\n if (logalot) { console.log(`${lc} ${ib}`); }\n return ib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * helper function that checks if an incoming `ib` or `ibGib.ib` indicates that\n * it is an arg ibGib used with witnesses.\n *\n * ## notes\n * * atow, this basically just checks to see if it starts with\n * `WITNESS_ARG_METADATA_STRING` (`witness_arg`).\n *\n * @throws if neither `ib` nor `ibGib` are provided.\n *\n * @returns true if the ib/ibGib.ib indicates an arg ibgib, else false\n *\n * @see {@link argy_}\n */\nexport function isArg({\n ib,\n ibGib,\n}: {\n ib?: Ib,\n ibGib?: IbGib_V1,\n}): boolean {\n const lc = `[${isArg.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!ib) {\n if (ibGib) {\n ib = ibGib.ib;\n } else {\n throw new Error(`either ib or ibGib required (E: c052a9d76df867626f9ba17141cdce22)`);\n }\n }\n\n return ib.startsWith(WITNESS_ARG_METADATA_STRING);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Builds the ib for the witness result ibgib.\n *\n * @returns ib that we'll use when creating a witness result.\n */\nexport function getResultIb(ibMetadata: string | undefined): string {\n const lc = `[${getResultIb.name}]`;\n try {\n const ib = ibMetadata ?\n `${WITNESS_RESULT_METADATA_STRING} ${ibMetadata}` :\n WITNESS_RESULT_METADATA_STRING;\n if (logalot) { console.log(`${lc} ${ib}`); }\n return ib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * helper function that checks if an incoming `ib` or `ibGib.ib` indicates that\n * it is a result ibGib used with witnesses.\n *\n * ## notes\n * * atow, this basically just checks to see if it starts with\n * `WITNESS_ARG_METADATA_STRING` (`witness_arg`).\n *\n * @throws if neither `ib` nor `ibGib` are provided.\n *\n * @returns true if the ib/ibGib.ib indicates a result ibgib, else false\n *\n * @see {@link resulty_}\n */\nexport function isResult({\n ib,\n ibGib,\n}: {\n ib?: Ib,\n ibGib?: IbGib_V1,\n}): boolean {\n const lc = `[${isResult.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!ib) {\n if (ibGib) {\n ib = ibGib.ib;\n } else {\n throw new Error(`either ib or ibGib required (E: 7d32a54825764d8ea72a8a38cac14224)`);\n }\n }\n\n return ib.startsWith(WITNESS_RESULT_METADATA_STRING);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n/**\n * This builds the arg ibGib for a witness function.\n *\n * By default, this is considered a one-off ibGib. As such,\n * there is no dna and no uuid. The timestamp will be included, which\n * adds some metadata (and makes for a most-often unique tjp). If there\n * is something that needs to reference this result, it can use the\n * the ibgib's address.\n *\n * @returns Result (wrapper) ibGib for a `witness` function.\n */\nexport async function argy_<\n TArgData,\n TArgRel8ns extends IbGibRel8ns_V1,\n TArgIbGib extends IbGib_V1<TArgData, TArgRel8ns\n > = IbGib_V1<TArgData, TArgRel8ns>>({\n argData,\n ibMetadata,\n noTimestamp,\n }: {\n argData: TArgData,\n ibMetadata?: string,\n noTimestamp?: boolean,\n }): Promise<TArgIbGib> {\n const lc = `[${argy_.name}]`;\n try {\n const resArgIbGib = await factory.firstGen<TArgData>({\n ib: getArgIb(ibMetadata),\n parentIbGib: factory.primitive({ ib: WITNESS_ARG_METADATA_STRING }),\n data: argData,\n dna: false,\n noTimestamp,\n });\n if (resArgIbGib.newIbGib) {\n const { newIbGib: resultIbGib } = resArgIbGib;\n\n // clear out past, disregard any intermediate ibgibs.\n resultIbGib.rel8ns!.past = [];\n\n resultIbGib.gib = await sha256v1(resultIbGib);\n\n return (resultIbGib as TArgIbGib);\n } else {\n throw new Error(`create ibGib failed`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * This builds the result ibGib for a witness function.\n *\n * By default, the result is considered a one-off ibGib. As such,\n * there is no dna and no uuid. The timestamp will be included, which\n * adds some metadata (and makes for a most-often unique tjp). If there\n * is something that needs to reference this result, it can use the\n * the ibgib's address.\n *\n * @returns Result (wrapper) ibGib for a `witness` function.\n */\nexport async function resulty_<TResultData, TResultIbGib extends IbGib_V1<TResultData> = IbGib_V1<TResultData>>({\n resultData,\n ibMetadata,\n noTimestamp,\n}: {\n resultData: TResultData,\n ibMetadata?: string,\n noTimestamp?: boolean,\n}): Promise<TResultIbGib> {\n const lc = `[${resulty_.name}]`;\n try {\n const resResultIbGib = await factory.firstGen<TResultData>({\n ib: getResultIb(ibMetadata),\n parentIbGib: factory.primitive({ ib: WITNESS_RESULT_METADATA_STRING }),\n data: resultData,\n dna: false,\n noTimestamp,\n });\n if (resResultIbGib?.newIbGib) {\n const { newIbGib: resultIbGib } = resResultIbGib;\n\n // clear out past, disregard any intermediate ibgibs.\n resultIbGib.rel8ns!.past = [];\n\n resultIbGib.gib = await sha256v1(resultIbGib);\n\n return resultIbGib as TResultIbGib;\n } else {\n throw new Error(`create ibGib failed`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * If valid, returns null.\n */\nexport function validateWitnessClassname({\n classname,\n}: {\n classname: string,\n}): string | null {\n const lc = `[${validateWitnessClassname.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!classname) { throw new Error(`classname required (E: b1c7b455d58fdd8d77acd15bdf017722)`); }\n\n if (!classname.match(CLASSNAME_REGEXP)) {\n return `classname (${classname}) must match regex ${CLASSNAME_REGEXP}`;\n }\n\n return null;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * @throws if `ibGib` falsy.\n *\n * @returns true ibGib indicates a cmd arg ibgib, else false\n */\nexport function isCommand({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): boolean {\n const lc = `[${isCommand.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!ibGib) { throw new Error(`ibGib required (E: e11cee2a6c59a5e7a4d39ea55751c423)`); }\n\n if (!ibGib.data) {\n return false; /* <<<< returns early */\n }\n\n const cmdData = (ibGib.data as WitnessCmdData<any, any>);\n return (cmdData.cmd && typeof (cmdData.cmd) === 'string');\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function fnToWitness({\n fn,\n}: {\n fn: (arg: IbGib_V1) => Promise<IbGib_V1>,\n}): Promise<Witness<any, any, any, any>> {\n const lc = `[${fnToWitness.name}]`;\n try {\n\n throw new Error(`not impl (E: 44d548c2656dc6bf27715a0ff606f223)`);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n\n }\n}\n\nexport function isWitness({ ibGib }: { ibGib: IbGib_V1 }): boolean {\n const lc = `[${isWitness.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: aad0a14f4d62061424fc92da4d53d823)`); }\n return typeof (ibGib as WitnessAny).witness === 'function';\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { WitnessBase_V1, } from '../witness-base-v1.mjs';\nimport {\n GetDependencyGraphResultData, IbGibSpace, IbGibSpaceData,\n IbGibSpaceOptionsCmd, IbGibSpaceOptionsCmdModifier, IbGibSpaceOptionsData,\n IbGibSpaceOptionsIbGib, IbGibSpaceOptionsRel8ns, IbGibSpaceRel8ns,\n IbGibSpaceResultData, IbGibSpaceResultIbGib, IbGibSpaceResultRel8ns\n} from './space-types.mjs';\nimport { getSpaceResultMetadata } from './space-helper.mjs';\nimport { getDependencyGraph, GetGraphOptions } from '../../common/other/graph-helper.mjs';\nimport { argy_, resulty_ } from '../../witness/witness-helper.mjs';\nimport { IbGibCacheService } from '../../common/cache/cache-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport interface IbGibSpaceAny\n extends SpaceBase_V1<any, any, any, any, any, any, any> {\n}\n\nexport abstract class SpaceBase_V1<\n TIbGib extends IbGib_V1 = IbGib_V1,\n TOptionsData extends IbGibSpaceOptionsData = IbGibSpaceOptionsData,\n TOptionsRel8ns extends IbGibSpaceOptionsRel8ns = IbGibSpaceOptionsRel8ns,\n TOptionsIbGib extends IbGibSpaceOptionsIbGib<TIbGib, TOptionsData, TOptionsRel8ns>\n = IbGibSpaceOptionsIbGib<TIbGib, TOptionsData, TOptionsRel8ns>,\n TResultData extends IbGibSpaceResultData = IbGibSpaceResultData,\n TResultRel8ns extends IbGibSpaceResultRel8ns = IbGibSpaceResultRel8ns,\n TResultIbGib extends IbGibSpaceResultIbGib<TIbGib, TResultData, TResultRel8ns>\n = IbGibSpaceResultIbGib<TIbGib, TResultData, TResultRel8ns>,\n TData extends IbGibSpaceData = IbGibSpaceData,\n TRel8ns extends IbGibSpaceRel8ns = IbGibSpaceRel8ns,\n>\n extends WitnessBase_V1<\n TOptionsData, TOptionsRel8ns, TOptionsIbGib,\n TResultData, TResultRel8ns, TResultIbGib,\n TData, TRel8ns>\n implements IbGibSpace<TIbGib, TOptionsData, TOptionsRel8ns, TOptionsIbGib, TResultData, TResultRel8ns, TResultIbGib, TData, TRel8ns> {\n\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${SpaceBase_V1.name}]`;\n\n /**\n * Optional cache service. hmm...\n */\n cacheSvc: IbGibCacheService | undefined;\n\n // getSpaceIb(classname: string): string {\n // const lc = `${this.lc}[${this.getSpaceIb.name}]`;\n // if (!classname) {\n // classname = this.lc?.replace('[','').replace(']','') || SpaceBase_V1.name+'_descendant';\n // console.warn(`${lc} classname is falsy. Using ${classname}.`);\n // }\n // const name = this.data?.name || IBGIB_SPACE_NAME_DEFAULT;\n // const id = this.data?.uuid || undefined;\n // return `witness space ${classname} ${name} ${id}`;\n // }\n\n constructor(initialData?: TData, initialRel8ns?: TRel8ns) {\n super(initialData, initialRel8ns);\n this.initialized = this.initialize();\n }\n\n /**\n * In a Space, we are concerned with getting ibGibs out of and putting ibGibs into a \"space\".\n *\n * So in this base, we take the incoming arg and divert it multiple ways, depending on our settings.\n */\n protected async witnessImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.witnessImpl.name}]`;\n if (logalot) { console.log(`${lc}`); }\n\n // do the thing\n let result = await this.routeAndDoCommand({\n cmd: arg.data!.cmd,\n cmdModifiers: arg.data!.cmdModifiers ?? [],\n arg,\n });\n\n // persist the arg and result if we're configured to do so\n // if (result && this.data.persistOptsAndResultIbGibs) {\n // try {\n // await this.persistOptsAndResultIbGibs({arg, result});\n // } catch (error) {\n // const emsg = `${lc} ${error.message}`;\n // console.error(emsg);\n // }\n // }\n\n return result;\n }\n\n protected abstract persistOptsAndResultIbGibs({ arg, result }:\n { arg: TOptionsIbGib, result: TResultIbGib }): Promise<void>;\n\n /**\n * Routes the given `cmd` to the correct handling function in the space,\n * and executes that function.\n *\n * Override this if you have custom commands to handle.\n * Check for those first, and if not among them, call this\n * via `super.doCommand(...)`. If cmd is still not found,\n * this will throw.\n */\n protected routeAndDoCommand<TCmdModifier extends IbGibSpaceOptionsCmdModifier = IbGibSpaceOptionsCmdModifier>({\n cmd,\n cmdModifiers,\n arg,\n }: {\n cmd: IbGibSpaceOptionsCmd | string,\n cmdModifiers: (TCmdModifier | string)[],\n arg: TOptionsIbGib,\n }): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.routeAndDoCommand.name}]`;\n switch (cmd) {\n case IbGibSpaceOptionsCmd.get:\n if ((cmdModifiers ?? []).length === 0) {\n return this.get(arg);\n } else if (cmdModifiers.includes('can')) {\n return this.canGet(arg);\n } else if (cmdModifiers.includes('latest')) {\n if (cmdModifiers.includes('addrs')) {\n return this.getLatestAddrs(arg);\n } else {\n return this.getLatestIbGibs(arg);\n }\n } else if (cmdModifiers.includes('tjps')) {\n if (cmdModifiers.includes('addrs')) {\n return this.getTjpAddrs(arg);\n } else {\n return this.getTjpIbGibs(arg);\n }\n } else if (cmdModifiers.includes('addrs')) {\n return this.getAddrs(arg);\n } else if (cmdModifiers.includes('dependency-graph')) {\n return this.getDependencyGraph(arg);\n } else {\n return this.get(arg);\n }\n\n case IbGibSpaceOptionsCmd.put:\n if ((cmdModifiers ?? []).length === 0) {\n return this.put(arg);\n } else if (cmdModifiers.includes('can')) {\n return this.canPut(arg);\n } else {\n return this.put(arg);\n }\n\n case IbGibSpaceOptionsCmd.delete:\n if ((cmdModifiers ?? []).length === 0) {\n return this.delete(arg);\n } else if (cmdModifiers.includes('can')) {\n return this.canDelete(arg);\n } else {\n return this.delete(arg);\n }\n\n default:\n throw new Error(`${lc} unknown cmd: ${cmd}. cmdModifiers: ${cmdModifiers}`);\n }\n }\n\n protected get(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getImpl(arg); }\n protected abstract getImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined>;\n\n protected put(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.putImpl(arg); }\n protected abstract putImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined>;\n\n protected delete(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.deleteImpl(arg); }\n protected deleteImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.deleteImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Get all (public?) addrs in space.\n *\n * @optional method for space.\n *\n * @returns all addresses in space (that it wants to reveal).\n */\n protected getAddrs(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getAddrsImpl(arg); }\n protected getAddrsImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.getAddrsImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Get latest ibGibs for given ibGib addresses.\n *\n * Usually I pass in the tjp address(es) if I have them.\n *\n * @optional method for space.\n *\n * @returns latest ibGibs in timelines for each given ibgib address.\n */\n protected getLatestIbGibs(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getLatestIbGibsImpl(arg); }\n protected getLatestIbGibsImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.getLatestIbGibsImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Get latest addrs for given ibGib(s)/address(es).\n *\n * Usually I pass in the tjp address(es) if I have them.\n *\n * @optional method for space.\n *\n * @returns latest addrs in timelines for each given ibgib address.\n */\n protected getLatestAddrs(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getLatestAddrsImpl(arg); }\n protected getLatestAddrsImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.getLatestAddrsImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Get temporal junction point ibgibs for given ibgib(s) or address(es).\n *\n * @optional method for space.\n *\n * @returns tjp ibgib for each given ibgib/address.\n */\n protected getTjpIbGibs(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getTjpIbGibsImpl(arg); }\n protected getTjpIbGibsImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.getTjpIbGibsImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Get temporal junction point addr(s) for given ibgib(s) or address(es).\n *\n * @optional method for space.\n *\n * @returns tjp addrs in timelines for each given ibgib/address.\n */\n protected getTjpAddrs(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getTjpAddrsImpl(arg); }\n protected getTjpAddrsImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.getTjpAddrsImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Supposed to be a check on either authorization, accessibility, existence...\n *\n * @notimplementedyet\n */\n protected canGet(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.canGetImpl(arg); }\n protected canGetImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.canGetImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Supposed to be a check on either authorization, accessibility, existence...\n *\n * @notimplementedyet\n */\n protected canPut(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.canPutImpl(arg); }\n protected canPutImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.canPutImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * Supposed to be a check on either authorization, accessibility, existence...\n *\n * @notimplementedyet\n */\n protected canDelete(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.canPutImpl(arg); }\n protected canDeleteImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.canDeleteImpl.name}]`;\n throw new Error(`${lc} not implemented in base class`);\n }\n\n /**\n * gets the entire dependency graph(s) of incoming addr(s).\n * \n * NOTE: Caller will have to manually convert the result.ibGibs to a flag\n * ibgib graph to match the existing {@link getDependencyGraph} return if\n * desired. This should be a trivial conversion though, as the keys to the\n * flat graph are just the {@link getIbGibAddr} on the ibGib itself.\n * \n * @returns resulty ibgib with {@link GetDependencyGraphResultData}\n */\n protected getDependencyGraph(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> { return this.getDependencyGraphImpl(arg); }\n /**\n * Default implementation of getDependencyGraph uses the helper function\n * {@link getDependencyGraph} in space-helpers.mts.\n * \n * Override this in subclasses for optimized behavior (e.g. Postgres).\n */\n protected async getDependencyGraphImpl(arg: TOptionsIbGib): Promise<TResultIbGib | undefined> {\n const lc = `${this.lc}[${this.getDependencyGraphImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0e5fe807a0169224781f6c2833f34826)`); }\n if (!arg.data) { throw new Error(`(UNEXPECTED) arg.data falsy? (E: 45eba816295a97a0e55f981861a03f26)`); }\n if ((arg.data.ibGibAddrs ?? []).length === 0) {\n throw new Error(`arg.data.ibGibAddrs is falsy/empty (E: 70adc939c7b80c9938d8fa18fd7c5826)`);\n }\n const opts: GetGraphOptions = {\n space: this,\n ibGibAddrs: arg.data.ibGibAddrs!,\n live: (arg.data as any).live || true,\n };\n const graph = await getDependencyGraph(opts);\n const ibGibs = Object.values(graph) as TIbGib[];\n const resultData: GetDependencyGraphResultData = {\n optsAddr: getIbGibAddr({ ibGib: arg }),\n count: ibGibs.length,\n addrs: Object.keys(graph),\n };\n return this.resulty({\n resultData: resultData as any as TResultData,\n ibGibs,\n });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Centralized location for general argument validation for a given witness.\n *\n * In the case of spaces, this is where I usually put my common validation\n * for various cases on cmd+modifier combinations.\n *\n * @returns validation error string, empty if no errors.\n */\n protected async validateWitnessArg(arg: TOptionsIbGib): Promise<string[]> {\n const lc = `${this.lc}[${this.validateWitnessArg.name}]`;\n let errors: string[] = [];\n try {\n errors = await super.validateWitnessArg(arg);\n if (!arg.data) {\n errors.push(`arg.data required (E: 8ee544d7d88a45c6adcbc15838a283a7)`);\n return errors; // <<<< returns immediately\n }\n if (!this.data) {\n errors.push(`this.data required (E: 64f80642d7de44329355d6f907e272c8)`);\n return errors; /* <<<< returns early */\n }\n\n const { cmd, ibGibAddrs, } = arg.data!;\n let cmdModifiers = arg.data!.cmdModifiers ?? [];\n const ibGibs = arg.ibGibs;\n if (!cmd) { errors.push(`arg.data.cmd required (E: 72a11ee87a0d4896bcacd65a9c0284d9)`); }\n if (!Object.values(IbGibSpaceOptionsCmd).includes((cmd as any))) { errors.push(`unknown arg.data.cmd: ${cmd}. (E: 95282ce61e97429f8049e61ec9f14f0b)`); }\n const ibGibAddrsLength = ibGibAddrs?.length ?? 0;\n if (\n cmd === IbGibSpaceOptionsCmd.get &&\n !cmdModifiers?.includes('addrs') && // we allow get addrs to be get ALL addrs\n !cmdModifiers?.includes('latest') &&\n ibGibAddrsLength === 0\n ) {\n errors.push(`ibGibAddrs required when cmd is ${cmd}. (E: ee55a3f60b90423cbe054f27c34ab7d5)`);\n }\n if (cmd === IbGibSpaceOptionsCmd.put) {\n if (logalot) { console.log(`${lc} validate put cmd`); }\n const ibGibsLength = ibGibs?.length ?? 0;\n if (ibGibsLength === 0) {\n errors.push(`ibGibs required when cmd is ${cmd}. (E: b3a422169f7344a48a1d44e7ad1ba44e)`);\n } else if (this.data.validateIbGibAddrsMatchIbGibs) {\n // #region validate ibGib map to ibGibAddrs\n if (logalot) { console.log(`${lc} validateIbGibAddrsMatchIbGibs true, so doing so.`); }\n\n // confirm the incoming ibGibs match up with the addresses\n // we have in `ibGibAddrs`.\n if (ibGibsLength !== ibGibAddrsLength) {\n errors.push(`ibGibsLength !== ibGibAddrsLength and this.data.validateIbGibAddrsMatchIbGibs is true. (E: 6c6bf824ab32443aa4d6b8bf4f8113dd)`);\n } else {\n // lengths match, so validate ibgibs\n if (logalot) { console.log(`${lc} validateIbGibAddrsMatchIbGibs, lengths match. validating intrinsically`); }\n const ibGibAddrsCopy = ibGibAddrs!.concat();\n for (let i = 0; i < ibGibs!.length; i++) {\n const ibGib = ibGibs![i];\n const intrinsicErrors = await validateIbGibIntrinsically({ ibGib });\n if (intrinsicErrors?.length ?? 0 > 0) {\n const addr = getIbGibAddr({ ibGib });\n // for privacy it might be nice to not have the\n // addr in the error msg, but it's too blind to\n // only have the gib right now.\n intrinsicErrors!.forEach(x => errors.push(`(${addr}) ERROR: ${x}`));\n } else {\n // intrinsically valid, but ensure the ibGib\n // addr maps 1-to-1 in ibGibAddrs\n const xAddr = getIbGibAddr({ ibGib });\n const xIndex = ibGibAddrsCopy.indexOf(xAddr);\n if (xIndex === -1) {\n errors.push(`ibGibAddrs don't map to calculated ibGib addrs. calculated Addr: (${xAddr}) (E: b21b3a7a74db43e5a8722acc97274646)`);\n break;\n } else {\n ibGibAddrsCopy.splice(xIndex, 1);\n }\n }\n }\n }\n\n // #endregion validate ibGib map to ibGibAddrs\n }\n }\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (errors?.length > 0) { console.error(`${lc} errors: ${errors}`); }\n }\n }\n\n /**\n * builds an arg ibGib.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async argy({\n argData,\n ibMetadata,\n noTimestamp,\n ibGibs,\n }: {\n argData: TOptionsData,\n ibMetadata?: string,\n noTimestamp?: boolean,\n ibGibs?: TIbGib[],\n }): Promise<TOptionsIbGib> {\n const arg = await argy_<TOptionsData, TOptionsRel8ns, TOptionsIbGib>({\n argData,\n ibMetadata,\n noTimestamp\n });\n\n if (ibGibs) { arg.ibGibs = ibGibs; }\n\n return arg;\n }\n\n /**\n * builds a result ibGib.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async resulty({\n resultData,\n ibGibs,\n }: {\n resultData: TResultData,\n ibGibs?: TIbGib[],\n }): Promise<TResultIbGib> {\n const result = await resulty_<TResultData, TResultIbGib>({\n ibMetadata: getSpaceResultMetadata({ space: this }),\n resultData,\n });\n if (ibGibs) { result.ibGibs = ibGibs; }\n return result;\n }\n\n}\n", "import { clone, extractErrorMsg, getTimestampInTicks, hash, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { Gib, Ib, IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1, IbGibRel8ns_V1, GIB, ROOT, isPrimitive, getGib, getGibInfo, GIB_DELIMITER, } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport { SpaceBase_V1 } from '../space-base-v1.mjs';\nimport {\n IbGibSpaceData, IbGibSpaceOptionsData, IbGibSpaceOptionsRel8ns,\n IbGibSpaceOptionsIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns,\n IbGibSpaceResultIbGib,\n IbGibSpaceData_Subpathed\n} from '../space-types.mjs';\nimport { argy_ } from '../../witness-helper.mjs';\nimport { isBinary, getBinHashAndExt, hasTjp, isTjp_Naive, getTimestampInfo, } from '../../../common/other/ibgib-helper.mjs';\nimport { parseSpaceIb, getSpaceIb, getSpecialIbGib, getTjpIbGib, } from '../space-helper.mjs';\nimport { DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS, IBGIB_SPACE_NAME_DEFAULT, ZERO_SPACE_ID } from '../space-constants.mjs';\nimport {\n Directory, Encoding,\n GetIbGibFileOpts, GetIbGibFileResult,\n PutIbGibFileOpts, PutIbGibFileResult,\n DeleteIbGibFileOpts, DeleteIbGibFilesResult,\n} from './filesystem-types.mjs';\nimport {\n IBGIB_BASE_SUBPATH, IBGIB_SPACE_SUBPATH_DEFAULT, IBGIB_BASE_DIR,\n IBGIB_ENCODING, IBGIB_IBGIBS_SUBPATH, IBGIB_META_SUBPATH,\n DEFAULT_FILESYSTEM_SPACE_DESCRIPTION,\n IBGIB_BIN_SUBPATH,\n IBGIB_DNA_SUBPATH,\n DEFAULT_LONG_PATH_LENGTH,\n IBGIB_LONG_SUBPATH,\n DEFAULT_PATH_SEPARATOR,\n ARBITRARY_IB_SUBSTRING_LENGTH_FOR_MITIGATE_LONG_PATH,\n} from './filesystem-constants.mjs';\nimport { isMetaStone, parseMetaStoneIb, validateCommonMetaStoneIbGib } from '../../../common/meta-stone/meta-stone-helper.mjs';\nimport { MetaStoneIbGib_V1, MetaStoneIbInfo } from '../../../common/meta-stone/meta-stone-types.mjs';\nimport { META_STONE_TARGET_REL8N_NAME } from '../../../common/meta-stone/meta-stone-constants.mjs';\nimport { BinIbGib_V1 } from '../../../common/bin/bin-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n// #region tmp\n\n// export async function tryRead({\n// path,\n// directory,\n// encoding,\n// }: {\n// path: string,\n// directory: string,\n// encoding: string,\n// // directory: Directory,\n// // encoding: Encoding,\n// }): Promise<string | null> {\n// const lc = `[${tryRead.name}]`;\n// try {\n// if (logalot) {\n// console.log(`${lc} starting...`);\n// if (path.includes('bootstrap^gib')) { console.log(`${lc} trying bootstrap^gib... (I: dacfdbe5a2d640ab947a7c17e3c56f78)`); }\n// }\n// throw new Error(`not implemented over from ionic-space yet (E: 3f60f152a449467a3ed53ac3c28f8523)`);\n// // const resRead = await Filesystem.readFile({\n// // path: path,\n// // directory,\n// // encoding,\n// // });\n// // if (logalot) { console.log(`${lc} path found: ${path} (I: 82e3ad9821bd4bf8a54c8facc61dbad0)`); }\n// // return resRead;\n// } catch (error) {\n// if (logalot) { console.log(`${lc} path not found: ${path} (I: 1fde689d29aa47fcb589b3e7dac8929b)`); }\n// return null;\n// } finally {\n// if (logalot) { console.log(`${lc} complete. (I: e2615c944a464cd48a5635fe401562d9)`); }\n// }\n// }\n\n// #endregion tmp\n\n// #region Space related interfaces/constants\n\n/**\n * This is the shape of data about this space itself (not the contained ibgibs' spaces).\n */\nexport interface FilesystemSpaceData_V1 extends IbGibSpaceData_Subpathed {\n /**\n * Redeclared here to make this required (not optional)\n */\n uuid: string;\n baseDir: Directory;\n encoding: Encoding;\n}\n\n/**\n * Used in bootstrapping.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nconst DEFAULT_FILESYSTEM_SPACE_DATA_V1: FilesystemSpaceData_V1 = {\n version: '3',\n uuid: ZERO_SPACE_ID,\n name: IBGIB_SPACE_NAME_DEFAULT,\n classname: 'FilesystemSpace_V1',\n baseDir: IBGIB_BASE_DIR,\n encoding: IBGIB_ENCODING,\n baseSubPath: IBGIB_BASE_SUBPATH,\n spaceSubPath: IBGIB_SPACE_SUBPATH_DEFAULT,\n ibgibsSubPath: IBGIB_IBGIBS_SUBPATH,\n metaSubPath: IBGIB_META_SUBPATH,\n binSubPath: IBGIB_BIN_SUBPATH,\n dnaSubPath: IBGIB_DNA_SUBPATH,\n longSubPath: IBGIB_LONG_SUBPATH,\n longPathLength: DEFAULT_LONG_PATH_LENGTH,\n mitigateLongPaths: true,\n persistOptsAndResultIbGibs: false,\n validateIbGibAddrsMatchIbGibs: false,\n longPollingIntervalMs: DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,\n allowPrimitiveArgs: false,\n catchAllErrors: true,\n description: DEFAULT_FILESYSTEM_SPACE_DESCRIPTION,\n trace: false,\n}\n\n/** Marker interface atm */\nexport interface FilesystemSpaceRel8ns_V1 extends IbGibRel8ns_V1 { }\n\n/**\n * Space options involve whether we're getting/putting ibgibs categorized as\n * meta, bin, dna.\n *\n * We'll leverage the fact that we don't need to get dna very often, and that\n * meta ibgibs act differently and are recorded differently.\n *\n * For example, we don't necessarily want to keep the past of certain meta\n * objects, because it may change (and thus grow) too quickly.\n */\nexport interface FilesystemSpaceOptionsData extends IbGibSpaceOptionsData {\n /**\n * Are we looking for a DNA ibgib?\n */\n isDna?: boolean;\n}\n\nexport interface FilesystemSpaceOptionsRel8ns extends IbGibSpaceOptionsRel8ns {\n}\n\n/** Marker interface atm */\nexport interface FilesystemSpaceOptionsIbGib<TData extends FilesystemSpaceOptionsData, TRel8ns extends FilesystemSpaceOptionsRel8ns>\n extends IbGibSpaceOptionsIbGib<IbGib_V1, TData, TRel8ns> {\n}\n\n/** Marker interface atm */\nexport interface FilesystemSpaceResultData extends IbGibSpaceResultData {\n}\n\nexport interface FilesystemSpaceResultRel8ns extends IbGibSpaceResultRel8ns {\n}\n\nexport interface FilesystemSpaceResultIbGib<TData extends FilesystemSpaceResultData, TRel8ns extends FilesystemSpaceResultRel8ns>\n extends IbGibSpaceResultIbGib<IbGib_V1, FilesystemSpaceResultData, FilesystemSpaceResultRel8ns> {\n}\n\n// #endregion\n\n/**\n * basic validation for filesystem space\n */\nexport async function validateFilesystemSpace_V1Intrinsically({ space }:\n { space: FilesystemSpace_V1<any, any, any, any> }): Promise<string[] | null> {\n const lc = `[${validateFilesystemSpace_V1Intrinsically.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: fcfe57145426ab4a5a0e961e87001922)`); }\n const errors: string[] = (await validateIbGibIntrinsically({ ibGib: space })) ?? [];\n\n const { ib, gib, data, rel8ns } = space;\n\n if (!ib) { errors.push('ib required. (E: a67fbb88841048f0a5bbf5ea266d7789)'); }\n if (!gib) { errors.push('gib required. (E: c811ce87f1e042769d0a43ff56091e22)'); }\n if (gib === GIB) { errors.push('gib cannot be primitive. (E: 5933bb715efc4e7cb74383d69d55ca64)'); }\n\n if (!data) {\n errors.push('data required. (E: 0b358c37f244422a96c7edb638b5ec00)');\n return errors;\n }\n\n if (!data.name) { errors.push('space name required. (E: f66412cd4d4e43ebb3cef55f91914f7c)') }\n\n if (!data.baseDir) { errors.push(`data.baseDir required. (E: 9df11d82a4bc4da38765c8e21ed9bace)`) }\n if (!data.baseSubPath) { errors.push(`data.baseSubPath required. (E: a44d3afec8b345d49480a640b33edfcd)`) }\n if (!data.binSubPath) { errors.push(`data.binSubPath required. (E: 52896e2405e842ebb7b5b11419556873)`) }\n if (!data.dnaSubPath) { errors.push(`data.dnaSubPath required. (E: 698a7853722b4e99927570231c350434)`) }\n if (!data.ibgibsSubPath) { errors.push(`data.ibgibsSubPath required. (E: f254076e67324969b5b2361d1fc514fb)`) }\n if (!data.metaSubPath) { errors.push(`data.metaSubPath required. (E: b675033dd2584fafbfe7a96d0c33b444)`) }\n if (data.n && typeof data.n !== 'number') { errors.push(`data.n must be a number. (E: a86fc07807594c90a4e67f9a7605b1b1)`) }\n if (data.n === undefined) {\n // the very first space record (tjp) has an undefined n and no rel8ns\n if (rel8ns) { errors.push(`rel8ns not expected when data.n is falsy (custom temporal junction point indicator I suppose...) (E: ef4317e9db9147abba66d75ffe63740b)`); }\n }\n if (!data.spaceSubPath) { errors.push(`data.spaceSubPath required. (E: 477d02f719bc45f08d133681c6e3f492)`) }\n if (!data.uuid) { errors.push(`data.uuid required. (E: 7ac3e7ae16ef47b78414b07b18d1a740)`) }\n if (!data.encoding) { errors.push(`data.encoding required. (E: 4f4baf9c9adf4a11a3357b7cfe450b92)`) }\n /** should probably get this from Capacitor... */\n const validEncodings = [\"utf8\", \"ascii\", \"utf16\"];\n if (!validEncodings.includes(data.encoding)) {\n errors.push(`invalid encoding: ${data.encoding}. validEncodings: ${validEncodings.join(', ')} (E: 0c910168b12f4f22935c3d23b23bbfd8)`);\n }\n\n // ensure ib matches up with internal data\n const { spaceClassname, spaceId, spaceName } = parseSpaceIb({ spaceIb: ib });\n if (data.classname && (spaceClassname !== data.classname)) {\n errors.push(`ib's spaceClassname (${spaceClassname}) must match data.classname (${data.classname}) (E: 57977f50d9bb4c64a0d06544023742a1)`);\n }\n if (spaceId !== data.uuid) {\n errors.push(`ib's spaceId (${spaceId}) must match data.uuid (${data.uuid}) (E: 03dd4d0d119b48a8a2d97c1444e2239e)`);\n }\n if (spaceName !== data.name) {\n errors.push(`ib's spaceName (${spaceName}) must match data.name (${data.name}) (E: 2cfa219c948f4fc8869d47b7217aed6f)`);\n }\n\n // ensure rel8ns make sense\n if (data.n === undefined && (rel8ns?.past ?? []).length > 0) {\n errors.push(`\"past\" rel8n not expected when data.n is falsy (E: 189bdfe41a7a46db947590d50c11ef88)`);\n }\n if (data.n && (rel8ns?.past ?? []).length === 0) {\n errors.push(`\"past\" rel8n required when data.n is truthy (E: abab9f88c898406497181c872b619276)`);\n }\n if (data.n === 0 && (rel8ns?.past ?? []).length !== 1) {\n errors.push(`\"past\" rel8n expected to have a single record when data.n === 0 (E: d5c9721b475d45ce9b94ba989bbc231b)`);\n }\n if (rel8ns && (rel8ns.past?.length ?? -1) > 0) {\n const pastAddrs = rel8ns.past as IbGibAddr[];\n pastAddrs.forEach(x => {\n const { ib: pastIb } = getIbAndGib({ ibGibAddr: x });\n const pastIbInfo = parseSpaceIb({ spaceIb: pastIb });\n if (pastIbInfo.spaceClassname && (pastIbInfo.spaceClassname !== spaceClassname)) {\n errors.push(`rel8ns.past address classname (${pastIbInfo.spaceClassname}) must match current spaceClassname (${spaceClassname}) (E: 51d859ab2e9f46279b9492c1a3ad1037)`);\n }\n if (pastIbInfo.spaceId !== spaceId) {\n errors.push(`rel8ns.past address spaceId (${pastIbInfo.spaceId}) must match current spaceId (${spaceId}) (E: 738a23cf54c947528e085cba24ab547a)`);\n }\n // i want to allow this, but for now we're going to require not changing the name...\n if (pastIbInfo.spaceName !== spaceName) {\n errors.push(`rel8ns.past address spaceName (${pastIbInfo.spaceName}) must match current spaceName (${spaceName}) (E: c0512b208885489eaf0d073613205fa7)`);\n }\n });\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Base class convenience for a local space with V1 ibgibs.\n *\n * This naively caches ibGibs in memory. When not found there,\n * will looks in files using Ionic `FileSystem`.\n */\nexport abstract class FilesystemSpace_V1<\n TOptionsData extends FilesystemSpaceOptionsData,\n TOptionsRel8ns extends FilesystemSpaceOptionsRel8ns,\n TResultData extends FilesystemSpaceResultData,\n TResultRel8ns extends FilesystemSpaceResultRel8ns,\n TData extends FilesystemSpaceData_V1 = FilesystemSpaceData_V1,\n TRel8ns extends FilesystemSpaceRel8ns_V1 = FilesystemSpaceRel8ns_V1\n> extends SpaceBase_V1<\n IbGib_V1,\n TOptionsData,\n TOptionsRel8ns,\n FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>,\n FilesystemSpaceResultData,\n FilesystemSpaceResultRel8ns,\n FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>,\n TData,\n TRel8ns\n> {\n\n /**\n * Log context for convenience with logging.\n */\n protected lc: string = `[${FilesystemSpace_V1.name}]`;\n\n /**\n * Naive caching in-memory. Memory leak as it stands right now!\n */\n protected ibGibs: { [key: string]: IbGib_V1 } = {};\n\n /**\n * Check every time app starts if paths exist.\n * But don't check every time do anything whatsoever.\n *\n * @see {@link ensureAllDirsExist}\n * @see {@link ensureDirsImpl}\n */\n protected pathExistsMap: { [key: string]: any } = {};\n\n constructor(\n // /**\n // * Default predicate value when putting an unknown ibGib.\n // *\n // * ## notes\n // *\n // * So when a repo witnesses another ibGib, it either defaults to\n // * storing that ibGib or not storing that ibGib. This is what that\n // * is referring to. If it's optimistic, then it stores any ibGib by\n // * default and it passes its put predicate.\n // */\n // public optimisticPut: boolean = true,\n initialData?: TData,\n initialRel8ns?: TRel8ns,\n ) {\n super(initialData ?? clone(DEFAULT_FILESYSTEM_SPACE_DATA_V1), initialRel8ns);\n }\n\n\n protected async validateWitnessArg(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>): Promise<string[]> {\n const lc = `${this.lc}[${this.validateWitnessArg.name}]`;\n let errors: string[] = [];\n try {\n errors = (await super.validateWitnessArg(arg)) || [];\n if (arg.data?.cmd === 'put' && (arg.ibGibs || []).length === 0) {\n errors.push(`when \"put\" cmd is called, ibGibs required.`);\n }\n if (arg.data?.cmd === 'get' && (arg.data?.ibGibAddrs || []).length === 0) {\n errors.push(`when \"get\" cmd is called, ibGibAddrs required.`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (errors?.length > 0) { console.error(`${lc} errors: ${errors}`); }\n }\n\n return errors;\n }\n\n /**\n * Initializes to default space values.\n */\n protected async initialize(): Promise<void> {\n const lc = `${this.lc}[${this.initialize.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!this.data) {\n this.data = clone(DEFAULT_FILESYSTEM_SPACE_DATA_V1);\n this.data = this.data!; // why does ts compiler need this?\n }\n if (!this.data?.classname) { this.data!.classname = FilesystemSpace_V1.name }\n if (!this.data.baseDir) { this.data.baseDir = IBGIB_BASE_DIR; }\n if (!this.data.encoding) { this.data.encoding = IBGIB_ENCODING; }\n if (!this.data.baseSubPath) { this.data.baseSubPath = IBGIB_BASE_SUBPATH; }\n if (!this.data.spaceSubPath) { this.data.spaceSubPath = IBGIB_SPACE_SUBPATH_DEFAULT; }\n if (!this.data.ibgibsSubPath) { this.data.ibgibsSubPath = IBGIB_IBGIBS_SUBPATH; }\n if (!this.data.metaSubPath) { this.data.metaSubPath = IBGIB_META_SUBPATH; }\n if (!this.data.binSubPath) { this.data.binSubPath = IBGIB_BIN_SUBPATH; }\n if (!this.data.dnaSubPath) { this.data.dnaSubPath = IBGIB_DNA_SUBPATH; }\n\n // do nothing, allow falsy\n // if (!this.data.longSubPath) { this.data.longSubPath = IBGIB_LONG_SUBPATH; }\n\n this.ib = getSpaceIb({ space: this, classname: FilesystemSpace_V1.name });\n\n this.gib = await getGib({ ibGib: this });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected hasInCache({ addr }: { addr: IbGibAddr }): Promise<boolean> {\n if (isPrimitive({ gib: getIbAndGib({ ibGibAddr: addr }).gib })) {\n // primitives never cached\n return Promise.resolve(false);\n } else if (Object.keys(this.ibGibs).includes(addr)) {\n // has in local instance cache\n return Promise.resolve(true);\n } else if (this.cacheSvc) {\n // not local so delegate to cache svc\n return this.cacheSvc.has({ addr });\n } else {\n // no external cache svc and not in local instance cache\n return Promise.resolve(false);\n }\n }\n protected async putInCache({ addr, ibGib }: { addr: IbGibAddr, ibGib: IbGib_V1 }): Promise<void> {\n const lc = `${this.lc}[${this.putInCache.name}][${addr}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!ibGib) { throw new Error(`ibGib required (E: 993e26fe40894bab9feccac3938f37df)`); }\n\n if (isPrimitive({ ibGib })) {\n if (logalot) { console.log(`${lc} skipping caching primitive (I: a04dfb691582a4db8a0bfecfefe5e622)`); }\n return;\n } else {\n if (logalot) { console.log(`${lc} caching addr (I: b996a306f256ee5f39db1e2f5d515c22)`); }\n }\n\n // instance cache\n this.ibGibs[addr] = ibGib;\n\n // cache svc\n if (this.cacheSvc) { await this.cacheSvc.put({ addr, ibGib }); }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n protected async getFromCache({ addr }: { addr: IbGibAddr }): Promise<IbGib_V1 | undefined> {\n const lc = `${this.lc}[${this.getFromCache.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n let cached: IbGib_V1 | undefined = this.ibGibs[addr];\n if (!cached && this.cacheSvc) {\n const info = await this.cacheSvc.get({ addr });\n cached = info?.ibGib;\n }\n return cached;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected deleteFromCache({ addr }: { addr: IbGibAddr }): Promise<void> {\n const lc = `${this.lc}[${this.getFromCache.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n delete this.ibGibs[addr];\n return Promise.resolve();\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async getImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.getImpl.name}]`;\n const resultIbGibs: IbGib_V1[] = [];\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n let notFoundIbGibAddrs: IbGibAddr[] | undefined = undefined;\n try {\n if (!arg.data) { throw new Error('arg.data is falsy'); }\n let { ibGibAddrs, isDna, } = arg.data!;\n\n ibGibAddrs ||= [];\n\n const binAddrs = ibGibAddrs.filter(addr => isBinary({ addr }));\n\n let ibGibAddrsNonBin = ibGibAddrs.filter(addr => !binAddrs.includes(addr));\n\n if (logalot) { console.log(`${lc} getting non-bin ibgibs. ibGibAddrsNonBin: ${ibGibAddrsNonBin}`); }\n for (let i = 0; i < ibGibAddrsNonBin.length; i++) {\n const addr = ibGibAddrsNonBin[i];\n if (!arg.data.force && await this.hasInCache({ addr })) {\n if (logalot) { console.log(`${lc} YES found in naive cache. (I: 0b23f394fd944c2a96df3543dd0a59c5)`); }\n const cached = await this.getFromCache({ addr });\n if (!cached) { throw new Error(`(UNEXPECTED) we had in cache but failed to retrieve? (E: 4af334f7a90cb22ffa3b549d0db19a22)`); }\n resultIbGibs.push(cached);\n } else {\n // not found in memory, so look in files\n // if (!isPrimitive({ gib: getIbAndGib({ ibGibAddr: addr }).gib }) && this.cacheSvc) {\n // }\n const getResult = await this.getFile({ addr, isDna, });\n if (getResult?.success && getResult.ibGib) {\n await this.putInCache({ addr, ibGib: getResult.ibGib })\n resultIbGibs.push(getResult.ibGib!);\n } else {\n // not found in memory or in files\n if (!notFoundIbGibAddrs) { notFoundIbGibAddrs = []; }\n notFoundIbGibAddrs.push(addr);\n }\n }\n }\n\n for (let i = 0; i < binAddrs.length; i++) {\n // debugger;\n const addr = binAddrs[i];\n const { binHash, binExt } = getBinHashAndExt({ addr });\n\n // getting binary, not a regular ibGib via addr\n if (logalot) { console.log(`${lc} getting binHash.binExt: ${binHash}.${binExt}`); }\n const getResult = await this.getFile({ addr });\n if (getResult?.success && getResult.ibGib) {\n if (logalot) { console.log(`${lc} getResult.success. ibGib.data?.length: ${getResult.ibGib!.data?.length}`); }\n resultIbGibs.push(getResult.ibGib);\n } else {\n if (logalot) { console.log(`${lc} not found in files. (binData is not cached atm)`) }\n // not found in files. (binData is not cached atm)\n if (!notFoundIbGibAddrs) { notFoundIbGibAddrs = []; }\n notFoundIbGibAddrs.push(addr);\n }\n }\n\n if (notFoundIbGibAddrs && notFoundIbGibAddrs.length > 0) {\n if (logalot) { console.log(`${lc}[${this.data!.uuid.substring(0, 8)}] notFoundIbGibAddrs: ${notFoundIbGibAddrs} (I: 10f7e35e75445a1d64b353851d00b923)`); }\n resultData.addrsNotFound = notFoundIbGibAddrs;\n resultData.errors ??= [];\n resultData.errors.push(`notFoundIbGibAddrs.length > 0 (E: e7eadcfa2f4643238590469bc917a35c)`);\n resultData.success = false;\n } else {\n resultData.success = true;\n }\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = [emsg];\n }\n try {\n const result = await this.resulty({ resultData });\n if (resultIbGibs.length > 0) {\n result.ibGibs = resultIbGibs;\n }\n return result;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n }\n\n protected async putImpl(\n arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>\n ): Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.putImpl.name}]`;\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n const errors: string[] = [];\n try {\n if (logalot) { console.log(`validating arg and internal state...`); }\n if (!arg.data) { throw new Error('arg.data required. (E: d64a46e5efab4b09b57850ecf0854386)'); }\n if (arg.ibGibs?.length === 0) { throw new Error(`arg.ibGibs required. (E: b4930d564b284fb9b26b542f14143a28)`); }\n\n if (logalot) { console.log(`arg and internal state validated...calling impl func`); }\n return await this.putIbGibsImpl(arg); // <<<< returns early\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = errors.concat([emsg]);\n resultData.success = false;\n }\n // only executes if there is an error.\n const result = await this.resulty({ resultData });\n return result;\n }\n\n protected async putIbGibsImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>\n ): Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.putIbGibsImpl.name}]`;\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n const errors: string[] = [];\n const warnings: string[] = [];\n const addrsErrored: IbGibAddr[] = [];\n try {\n if (!arg.data) { throw new Error('arg.data is falsy (E: aae5757c158d4a799deb7fca9d6245f0)'); }\n const { isDna, force } = arg.data!;\n const ibGibs = arg.ibGibs || [];\n const addrsAlreadyHave: IbGibAddr[] = [];\n\n for (let i = 0; i < ibGibs.length; i++) {\n const ibGib = ibGibs[i];\n const addr = getIbGibAddr({ ibGib });\n if (logalot) { console.log(`${lc} checking to see if already exists...`); }\n const getResult = await this.getFile({ addr, isDna });\n // const getResult: any = null; // testing performance\n if (getResult?.success && getResult.ibGib) {\n // already exists...\n if (logalot) { console.log(`${lc} already exists...`); }\n if (force) {\n // ...but save anyway.\n if (logalot) { console.log(`${lc} Forcing save of already put addr: ${addr} (I: 325f363e5d438b43c24b810c150e4e22)`); }\n const putResult = await this.putFile({ ibGib, isDna });\n if (putResult.success) {\n if (!isDna) {\n // naive cache will cause \"memory leak\" eventually\n await this.putInCache({ addr, ibGib });\n }\n } else {\n errors.push(putResult.errorMsg || `${lc} error putting ${addr}`);\n addrsErrored.push(addr);\n }\n } else {\n // ...so annotate\n // deb ugger;\n if (logalot) {\n warnings.push(`${lc} skipping (non-force) of already exists addr: ${addr} (W: b7fbe22473014dd090db88aee631fecb)`);\n }\n addrsAlreadyHave.push(addr);\n }\n } else {\n // does not already exist.\n if (logalot) { console.log(`${lc} does NOT already exist...`); }\n const putResult = await this.putFile({ ibGib, isDna, });\n if (putResult.success) {\n if (!isDna) { await this.putInCache({ addr, ibGib }); }\n } else {\n errors.push(putResult.errorMsg || `${lc} error putting ${addr}`);\n addrsErrored.push(addr);\n }\n }\n }\n\n if (addrsAlreadyHave.length > 0) { resultData.addrsAlreadyHave = addrsAlreadyHave; }\n if (warnings.length > 0) { resultData.warnings = warnings; }\n if (errors.length === 0) {\n resultData.success = true;\n } else {\n resultData.errors = errors;\n resultData.addrsErrored = addrsErrored;\n }\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = errors.concat([emsg]);\n resultData.addrsErrored = addrsErrored;\n resultData.success = false;\n }\n const result = await this.resulty({ resultData });\n return result;\n }\n\n protected async deleteImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.deleteImpl.name}]`;\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n const errors: string[] = [];\n const warnings: string[] = [];\n const addrsDeleted: IbGibAddr[] = [];\n const addrsErrored: IbGibAddr[] = [];\n try {\n if (!arg.data) { throw new Error('arg.data is falsy'); }\n const { isDna, } = arg.data!;\n const ibGibAddrs = arg.data!.ibGibAddrs || [];\n\n // delete cached entries first\n // const cachedAddrs = Object.entries(this.ibGibs)\n // .filter(([x,y]) => ibGibAddrs.includes(x))\n // .map(([x,y]) => x);\n // cachedAddrs.forEach(addr => { delete this.ibGibs[addr]; });\n\n // iterate through ibGibs, but this may be an empty array if we're doing binData.\n for (let i = 0; i < ibGibAddrs.length; i++) {\n const addr = ibGibAddrs[i];\n await this.deleteFromCache({ addr });\n const deleteResult = await this.deleteFile({ addr, isDna, });\n if (deleteResult?.success) {\n addrsDeleted.push(addr);\n } else {\n errors.push(deleteResult.errorMsg || `delete failed: addr (${addr})`);\n addrsErrored.push(addr);\n }\n }\n if (warnings.length > 0) { resultData.warnings = warnings; }\n if (errors.length === 0) {\n resultData.success = true;\n resultData.addrs = addrsDeleted;\n } else {\n resultData.errors = errors;\n resultData.addrsErrored = addrsErrored;\n if (addrsDeleted.length > 0) {\n const warningMsg =\n `some addrs (${addrsDeleted.length}) were indeed deleted, but not all. See result addrs and addrsErrored.`;\n resultData.warnings = (resultData.warnings || []).concat([warningMsg]);\n }\n }\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = errors.concat([emsg]);\n resultData.addrsErrored = addrsErrored;\n resultData.success = false;\n }\n const result = await this.resulty({ resultData });\n return result;\n }\n\n protected async getAddrsImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.getAddrsImpl.name}]`;\n throw new Error(`${lc} not implemented. (E: 74dd50ce4b564559bc44d6c08d446cb3)`);\n }\n\n /**\n * Performs a naive `exists: boolean` or `includes: boolean` analog.\n *\n * If all of the addresses are found, will result in `success` and `can` being `true`.\n *\n * Else, `can` will be falsy, and `addrsNotFound` will be populated with all/some of\n * the queried addresses.\n *\n * ## notes\n *\n * This does not take authorization into account in any way. it's a simple, naive in-memory\n * storage ibGib witness.\n *\n * @returns result ibGib whose primary value is `can`\n */\n protected async canGetImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.canGetImpl.name}]`;\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n try {\n throw new Error(`not implemented (E: 2a45977c584c6bbbc4f164c16106bd22)`);\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = [emsg];\n }\n const result = await this.resulty({ resultData });\n return result;\n }\n protected async canPutImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.canPutImpl.name}]`;\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n try {\n throw new Error(`not implemented (E: 25a005d496efc69faefdec155ffb4a22)`);\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = [emsg];\n }\n const result = await this.resulty({ resultData });\n return result;\n }\n\n protected async canDeleteImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.canDeleteImpl.name}]`;\n throw new Error(`${lc} not implemented (E: a3306138b4ac429ba5f8f293ad7dd07b)`);\n }\n\n protected async getLatestAddrsImpl(arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>):\n Promise<FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>> {\n const lc = `${this.lc}[${this.getLatestAddrsImpl.name}]`;\n const resultData: FilesystemSpaceResultData = { optsAddr: getIbGibAddr({ ibGib: arg }), }\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!arg.data) { throw new Error(`arg.data required (E: cd92cb965d711c8014455c69e898ac23)`); }\n if (!arg.data.ibGibAddrs) { throw new Error(`arg.data.ibGibAddrs required (E: 2d0824f9b8aec916a751ef17e2d4a823)`); }\n if (arg.data.ibGibAddrs.length === 0) { throw new Error(`arg.data.ibGibAddrs required to be non-zero (E: 2d0824f9b8aec916a751ef17e2d4a823)`); }\n\n const latestAddrs = new Set<IbGibAddr>();\n const addrsNotFound = new Set<IbGibAddr>();\n const addrsErrored = new Set<IbGibAddr>();\n resultData.latestAddrsMap = {};\n\n // iterate through incoming ibGibAddrs, get their corresponding\n // ibgib from file storage, and use our existing\n // `getLatestAddrImpl` function\n for (let i = 0; i < arg.data.ibGibAddrs.length; i++) {\n const addr = arg.data.ibGibAddrs[i];\n const getResult = await this.getFile({ addr });\n if (getResult?.success && getResult.ibGib) {\n const ibGib = getResult.ibGib!;\n const latestAddr = await this.getLatestAddrImpl({ ibGib });\n if (latestAddr) {\n latestAddrs.add(latestAddr);\n resultData.latestAddrsMap[addr] = latestAddr;\n } else {\n console.warn(`expecting latestAddr to either be assigned or throw. Adding addr (${addr}) to addrsErrored. (W: 35c3712b1a1e579ccf28c389eb2ecc22)`);\n addrsErrored.add(addr);\n }\n } else if (getResult?.success) {\n addrsNotFound.add(addr);\n resultData.latestAddrsMap[addr] = null;\n } else if (getResult.errorMsg) {\n addrsErrored.add(addr);\n } else {\n throw new Error(`unknown (invalid) getResult: ${pretty(getResult)} (E: 2674ad5d30294be29a3d3fdcf54ef6d9)`);\n }\n }\n\n resultData.addrs = latestAddrs.size > 0 ? [...latestAddrs] : undefined;\n resultData.addrsErrored = addrsErrored.size > 0 ? [...addrsErrored] : undefined;\n resultData.addrsNotFound = addrsNotFound.size > 0 ? [...addrsNotFound] : undefined;\n\n // we didn't throw, so that's a success\n resultData.success = true;\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} error: ${emsg}`);\n resultData.errors = [emsg];\n }\n try {\n let result = await this.resulty({ resultData });\n return result;\n } catch (error) {\n console.error(`${lc}[resulty] ${extractErrorMsg(error)}`);\n throw error;\n }\n }\n\n /**\n * @internal\n *\n * This is the actual implementation function to get a single latest address\n * for a single ibgib.\n *\n * @returns latest addr in this space according to the \"latest\" special ibgib index\n *\n * ## implementation notes\n *\n * ### pre-11/2023 Single SpecialIbGibType.latest \"special ibgib\" indexing\n *\n * an early implementation, this used a single meta \"special ibgib\" () that\n * is a central point in the space that maps from tjpAddr => latestAddr.\n * this makes it a bottleneck (not scalable) and a single point-of-failure\n * (not robust).\n *\n * ### 11/2023 (current atow 11/2023)\n *\n * default latest address mapping from tjpAddr => latestAddr implementation\n * candidates are considered here.\n *\n * #### individual constant-named files\n *\n * individual files inside /basePath/spaceSubpath/metaSubpath/latest. These\n * will have tjpAddr filename (no extension?) but the contents should simply\n * be the latestAddr.\n *\n * ##### advantages\n *\n * * this would require additional/specialized file getting/putting\n * implementations.\n * * this might be a proximally faster implementation as no additional\n * hashing would be required.\n *\n * ##### disadvantages\n *\n * mainly it is about possible security concerns on this implementation and\n * less ibgib dogfooding.\n *\n * I am unsure if this would be any \"less safe\" than the previous\n * implementation that relied on the special ibgib indexing, as even though\n * the latest special ibgib index was itself hashed, it was still ephemeral\n * and the space did not track changes to it. Either way, it is always a\n * security consideration to change the tjpAddr => latestAddr mapping as you\n * can hijack timelines. But this is mitigated as long as you have a\n * monotonically increasing space, you can correct any malfeasance and\n * \"stitch\" together the \"correct\" space state.\n *\n * Still, it would be good to have some timeline whose job is to snapshot\n * these periodically. Perhaps that is simply a functionality that would be\n * good to have regardless of \"security\" concerns. Reified checkpointing.\n *\n * #### meta latest ibgib stones (constants/no tjp themselves)\n *\n * instead of bare files, we reuse ibgib plumbing via ibgib stones with\n * special ib schemas that allow us to mimic a timeline with the following\n * information:\n *\n * * meta_latest [tjpGib] [n] [index timestamp ticks]\n *\n * _I mention this as mimicking a timeline because if we were to have them as\n * colocated ibgibs in space (not separated specially to ignore when sending\n * graphs), we would then have a recursive problem of keeping track of the\n * latest addrs of the latest addr tracking ibgibs (turtles all the way\n * down)._\n *\n * this would be put in a separate subpath underneath the meta subpath, or\n * possibly as a sibling beside it. definitely need a separate path though\n * for the same reason we have a separate path for dna. there will be many,\n * **many** of these constants. so much so that we may want to prune them on\n * some basis. Possibly will do sibling beside it to reduce overall path\n * length.\n *\n * the index timestamp ticks is the timestamp when the indexing occurs in\n * the local space (not the ibgib's internal timestamp, if it exists). I\n * wanted to add this also, but could be yagni and there is a cost with path\n * length implementations.\n *\n * ##### advantages\n *\n * * reuses existing get/put implementation\n * * allows consistent coding of helper functions/types/etc.\n * * allows for (future implementation) of on-chain schema information\n * * more robust against soft hacks\n * * soft = non-total access hacks\n * * allows for future consensus/witness backups/gossip\n *\n * overall would be less distal overhead (more simplification) and dogfoods\n * the ibgib protocol to a greater degree.\n *\n * ##### disadvantages\n *\n * * more proximal overhead\n * * already \"practical\" performance issues in prototype, though afaict\n * this is largely because i'm working solo on the darn project and i suck\n * at ux (i.e. angular)\n * * not just me, angular/react/others dispatching are necessarily overhead as\n * they duplicate some of the awesomeness that comes for free when starting with\n * ibgib timelines from the beginning.\n */\n protected async getLatestAddrImpl({\n ibGib,\n ibGibAddr,\n }: {\n ibGib?: IbGib_V1,\n ibGibAddr?: IbGibAddr,\n }): Promise<IbGibAddr> {\n let lc = `${this.lc}[${this.getLatestAddrImpl.name}]`;\n if (logalot) { console.log(`${lc} starting...`); }\n try {\n if (!ibGib && !ibGibAddr) { throw new Error(`either ibGib or ibGibAddr required (E: 1f8f0cb61d1b4c708b06762048735c22)`); }\n\n if (ibGib && ibGibAddr && (getIbGibAddr({ ibGib }) !== ibGibAddr)) { throw new Error(`(UNEXPECTED) both ibGib and ibGibAddr provided but they don't match? (E: 01d1938252ef49b53d41d58abfaac523)`); }\n\n ibGibAddr ||= getIbGibAddr({ ibGib });\n const { ib, gib } = getIbAndGib({ ibGibAddr });\n if (!gib) { throw new Error(`(UNEXPECTED) gib falsy? (E: d2506b99162e27348310f8e7e68e4523)`); }\n\n // first do some initial checking to rule out quick special cases...\n\n // if it's primitive, warn and return incoming addr\n if (isPrimitive({ gib })) {\n console.warn(`${lc} incoming ibGibAddr is primitive. Why are we calling getLatest on a primitive? returning incoming addr. (W: 57fcf479d5cc48d393841ec3d53587fa)`);\n return ibGibAddr; /* <<<< returns early */\n }\n const probablyIsDna = ['fork', 'mut8', 'rel8'].includes(ib);\n if (probablyIsDna) {\n if (logalot) { console.log(`${lc} probably is dna (ib === fork/mut8/rel8). returning incoming ibGibAddr early. (I: 2081628936de6a36bbb51224f0223523)`); }\n return ibGibAddr; /* <<<< returns early */\n }\n\n // at this point it might be...\n // 1) a stone (constant/no timeline)\n // 2) a tjp (data.isTjp is true)\n // 3) a timeline member (tjpGib in gib)\n // in any case, we can pull the tjpGib out of the addr. if it's falsy, we use the gib as\n // if it were the tjpGib.\n //\n\n const gibInfo = getGibInfo({ ibGibAddr });\n let { tjpGib } = gibInfo;\n tjpGib ||= gib;\n // if (!tjpGib) {\n // // may still itself be the tjp\n // if (!!ibGib.data?.isTjp) {\n // // the ibgib is itself the tjp, so it's gib is the tjpGib\n // tjpGib = gib;\n // } else {\n // // no tjp, just return the incoming ibGib\n // if (logalot) { console.log(`${lc} incoming ibGib has no tjp and is not itself the tjp. so it's a stone, not a timeline. returning incoming ibGibAddr. (I: 30bace867ea274cdc3263ab901c9dd23)`); }\n // return ibGibAddr; /* <<<< returns early */\n // }\n // }\n\n // guaranteed to have a tjp at this point & tjpGib is truthy\n\n // get the tjp for the rel8nName mapping, and also for\n // some checking logic\n // let tjp = await getTjpIbGib({ ibGib, space: this });\n // if (!tjp) {\n // throw new Error(`(UNEXPECTED) tjp not found for ${ibGibAddr}? Should at least just be the ibGib's address itself. (E: 860bdcaaf80548feb6b61b4cde21a722)`);\n // // console.warn();\n // // tjp = ibGib;\n // }\n // const tjpAddr = getIbGibAddr({ ibGib: tjp });\n // if (logalot) { console.log(`${lc} tjp (${tjpAddr}) (I: 5245a2ec85a943f98479e93a32d67f22)`); }\n\n // here is where the implementation change starts. instead of using\n // the special ibgib, we will look for the subfolder that corresponds to the tjpGib.\n\n // if we get a list of the metastone addrs in the folder, we can\n // filter for the highest n and latest timestampInTicks.\n // * do we need to load any actual files to do more searching?\n // * ensure that tjpGib matches in ib?\n // * is this an implementation detail that should only be in descendant class\n // * pass in lambda to do filtering in the function?\n const metaStoneAddrs = await this.getMetaStoneAddrs({ tjpGib, ibGibAddr });\n if (metaStoneAddrs.length === 0) {\n if (logalot) { console.warn(`${lc} no metastones found for given ibGibAddr (${ibGibAddr}). returning incoming ibGibAddr (W: a6a35cbbf40745e8a3e202226bb457ff)`); }\n return ibGibAddr; /* <<<< returns early */\n }\n\n // security-wise, a stronger implementation would verify each meta\n // stone intrinsically at the very least, as well as additional\n // checking once authorization/authentication/keystones are in use.\n // for now, we'll just take it for granted, as this provides the\n // same (lack of) security guarantees as previous implementation that\n // used the SpecialIbGibType.latest.\n\n const metaStoneAddrsAndIbInfos: [IbGibAddr, MetaStoneIbInfo][] = metaStoneAddrs\n .map(xAddr => [xAddr, getIbAndGib({ ibGibAddr: xAddr }).ib])\n .map(([xAddr, metaStoneIb]) => [xAddr, parseMetaStoneIb({ ib: metaStoneIb })]);\n\n\n /**\n * sort mutates the actual array (shuffle sort I think), but\n * we're storing it in a different variable name to be more\n * explicit.\n */\n const metaStoneAddrsAndIbInfos_descending = metaStoneAddrsAndIbInfos.sort((a, b) => {\n const [_aAddr, aInfo] = a;\n const [_bAddr, bInfo] = b;\n // we want the highest n, with tiebreaker going to\n // timestampInTicks. if that's the same also, then what are we\n // quibbling about?\n if (aInfo.n > bInfo.n) {\n return -1;\n } else if (aInfo.n < bInfo.n) {\n return 1;\n } else if (aInfo.timestampInTicks > bInfo.timestampInTicks) {\n return -1;\n } else if (aInfo.timestampInTicks < bInfo.timestampInTicks) {\n return 1;\n } else {\n // neither discriminator is different.\n return 0;\n }\n });\n if (logalot) {\n console.log(`${lc} console.dir(metaStoneAddrsAndIbInfos_descending)... (I: 1bb5e7d994248e8b6559ca2863c72123)`);\n console.dir(metaStoneAddrsAndIbInfos_descending);\n }\n\n // since we sorted into a descending order, the latest is the very\n // first item. and we have already guaranteed that there is at\n // least 1 in the array.\n if (metaStoneAddrsAndIbInfos_descending.length === 0) { throw new Error(`(UNEXPECTED) metaStoneAddrsAndIbInfos_descending is empty? earlier in the function there should have been a check. did getMetaStoneAddrs return a populated list but no stones were found? (E: 63c035ebed77741f2330c7a625823f23)`); }\n\n const [latestMetaStoneAddr, latestMetaStoneInfo] = metaStoneAddrsAndIbInfos_descending[0];\n if (logalot) { console.log(`${lc} [latestMetaStoneAddr, latestMetaStoneInfo]: ${[latestMetaStoneAddr, latestMetaStoneInfo]} (I: 1307ca46b4abd62c7a30fe87c08fa923)`); }\n\n let latestMetaStoneIbGib: MetaStoneIbGib_V1;\n const getResult = await this.getFile({ addr: latestMetaStoneAddr, isDna: false, });\n if (getResult?.success && getResult.ibGib) {\n latestMetaStoneIbGib = getResult.ibGib as MetaStoneIbGib_V1;\n const errors = await validateCommonMetaStoneIbGib({ ibGib: latestMetaStoneIbGib }) ?? [];\n if (errors.length > 0) { throw new Error(`invalid metastone (${latestMetaStoneAddr}) for tjpGib (${tjpGib}). errors: ${errors.join('|')} (E: 7fa7c6fa696d860cc7a9148861f96123)`); }\n } else {\n throw new Error(`(UNEXPECTED) we just found a metastone addr (${latestMetaStoneAddr}) that was read from the directory's contents, but we can't get the file? (E: 3b934b4adcd9d0efee7820f8d4012e23)`);\n }\n\n // latestMetaStoneIbGib.rel8ns ensured via validation at this point\n const latestMetaStoneRel8ns = latestMetaStoneIbGib.rel8ns!;\n /**\n * this is accurate as the punctiliar address that corresponds to\n * the metastone.\n *\n * atow (11/2023) interface of rel8ns\n * [META_STONE_TARGET_REL8N_NAME]: IbGibAddr[];\n * [META_STONE_TARGET_TJP_REL8N_NAME]?: IbGibAddr[];\n */\n const latestAddr = latestMetaStoneRel8ns[META_STONE_TARGET_REL8N_NAME].at(0);\n if (!latestAddr) { throw new Error(`metastone passed validation but latestMetaStoneRel8ns[META_STONE_TARGET_REL8N_NAME].at(0) is empty? (E: c188ec0089ad86efe4d925c118599d23)`); }\n return latestAddr;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n\n\n /**\n * Extremely crude implementation that just\n * saves the ibgibs alongside existing data.\n *\n * ## future\n *\n * * At the very least, this could be changed similar to dna to have\n * its own folder.\n */\n protected async persistOptsAndResultIbGibs({\n arg,\n result,\n }: {\n arg: FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>,\n result: FilesystemSpaceResultIbGib<TResultData, TResultRel8ns>,\n }): Promise<void> {\n const lc = `${this.lc}[${this.persistOptsAndResultIbGibs.name}]`;\n if (logalot || this.data?.trace) {\n console.log(`${lc} doing arg?.data?.cmd: ${arg?.data?.cmd}, result?.data?.success: ${result?.data?.success}`);\n }\n const ibGibs = [arg, result ?? ROOT];\n let argPersist = await argy_<FilesystemSpaceOptionsData, FilesystemSpaceOptionsRel8ns, FilesystemSpaceOptionsIbGib<TOptionsData, TOptionsRel8ns>>({\n argData: {\n cmd: 'put',\n catchAllErrors: true,\n ibGibAddrs: ibGibs.map(x => getIbGibAddr({ ibGib: x })),\n },\n });\n argPersist.ibGibs = ibGibs;\n // this is a best effort storage, so we aren't using the result\n // in the future, we should incorporate what to do if this persistence\n // fails into the larger success requirements of spaces.\n const resPut = await this.putIbGibsImpl(argPersist);\n if (!resPut?.data) { throw new Error(`resPut.data falsy (E: f3115254240b8eff6cd82878a4a35a23)`); }\n if (!resPut.data.success || resPut.data.errors) {\n console.error(`${lc} Errors persisting arg & result: ${(resPut.data?.errors ?? ['unknown errs']).join('\\n')}. (E: 65ef314a4f8e445d851dab5b290e9a03)`);\n }\n }\n\n // #region files related\n\n protected abstract putFile({\n ibGib,\n isDna,\n }: PutIbGibFileOpts): Promise<PutIbGibFileResult>;\n\n protected abstract deleteFile({\n addr,\n isDna,\n }: DeleteIbGibFileOpts): Promise<DeleteIbGibFilesResult>;\n\n protected abstract getFile({\n addr,\n isDna,\n }: GetIbGibFileOpts): Promise<GetIbGibFileResult>;\n\n // #endregion files related\n\n // #region ensure related\n\n protected async ensurePermissions(): Promise<boolean> {\n const lc = `${this.lc}[${this.ensurePermissions.name}]`;\n const keyPermissionRequested: string = 'ibgib_permissionRequested_ensurePermissions';\n try {\n return true;\n } catch (error) {\n console.error(`${lc} Dont have permissions... error: ${extractErrorMsg(error)}`);\n // localStorage.removeItem(keyPermissionRequested);\n return false;\n }\n }\n\n /**\n * Ensure directories are created on filesystem before trying to read/write\n * paths.\n */\n protected async ensureAllDirsExist(): Promise<void> {\n // does nothing in base impl\n // throw? i don't remember why i didn't have this throw...\n const lc = `${this.lc}[${this.ensureAllDirsExist.name}]`;\n console.warn(`${lc} not implemented in base class (W: c1b63ec036134db5960e0d3ea169d15b)`);\n }\n protected abstract ensureDirsImpl(paths: string[]): Promise<void>;\n\n // #endregion ensure related\n\n // #region metastone related\n\n /**\n * retrieves all metastone addrs whose targets have tjpGib\n */\n protected abstract getMetaStoneAddrs({\n ibGibAddr,\n tjpGib,\n fnFilterIb,\n }: {\n /**\n * addr of ibGib for which we're getting the metastones.\n */\n ibGibAddr: IbGibAddr,\n /**\n * tjpGib of the metastone's target ibgib\n */\n tjpGib: Gib,\n fnFilterIb?: (ib: Ib) => boolean,\n }): Promise<IbGibAddr[]>;\n\n /**\n * we are storing tjp-related things under the tjp subpath. so it will be\n * atow (11/2023) something like .ibgib/ibgib/ibgibs/[tjpGib]/[ibGibAddr].json.\n * i'm thinking that i should put the metastones inside a sub folder, so,\n * .ibgib/ibgib/ibgibs/[tjpGib]/meta/[metaStoneAddr].json\n *\n * NOTE: does NOT ensure that the subpath exists.\n *\n * ## driving use case\n *\n * in here is where i will be putting the metastones. but I'm thinking I\n * should store all ibgibs in this way, if they have a tjpGib. in fact, i\n * may want to store the metastones underneath this tjpGib subpath.\n *\n * @returns full path of the (possibly non-existent) directory.\n */\n protected getTjpSubpath({\n viaTargetAddr,\n viaTargetTjpGib,\n viaMetaStoneAddr,\n pathSeparator = DEFAULT_PATH_SEPARATOR,\n }: {\n /**\n * This param pulls the tjpGib from the target ibGib's address. (target\n * as opposed to a metastone that points to a target).\n *\n * If this target addr is a stone, then this will use the addr's gib.\n *\n * ## notes\n *\n * Ultimately the tjp subpath is built on an ibGib's tjpGib. We can get\n * this via multiple sources.\n *\n * _We only need to pass in one source, whichever is most convenient to\n * caller._\n */\n viaTargetAddr?: IbGibAddr,\n /**\n * This param provides the target's tjpGib directly. (target as opposed\n * to a metastone that points to a target).\n *\n * ## notes\n *\n * Ultimately the tjp subpath is built on an ibGib's tjpGib. We can get\n * this via multiple sources.\n *\n * _We only need to pass in one source, whichever is most convenient to\n * caller._\n */\n viaTargetTjpGib?: Gib,\n /**\n * This param provides the target's tjpGib based on the metaStone's ib,\n * whose schema includes the target tjpGib (target as opposed\n * to a metastone that points to a target).\n *\n * ## notes\n *\n * Ultimately the tjp subpath is built on an ibGib's tjpGib. We can get\n * this via multiple sources.\n *\n * _We only need to pass in one source, whichever is most convenient to\n * caller._\n */\n viaMetaStoneAddr?: IbGibAddr,\n /**\n * path separator to use when building the path.\n */\n pathSeparator?: string,\n }): string {\n const lc = `${this.lc}[${this.getTjpSubpath.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c65dabcf47acf6d6881087b404861e23)`); }\n\n // validate\n if (!viaTargetAddr && !viaTargetTjpGib && !viaMetaStoneAddr) {\n throw new Error(`either viaTargetAddr/TargetTjpGib/metaStoneAddr required (E: a784c4f0369e6e38eafcdf3289c38523)`);\n }\n if (!this.data) { throw new Error(`(UNEXPECTED) this.data falsy? (E: 441ff1b038366a1c07a94cf128454923)`); }\n if (!pathSeparator) {\n console.warn(`${lc} pathSeparator falsy? using default: \"${DEFAULT_PATH_SEPARATOR}\" (W: 295d21ab226743dd83a721f78870ab6e)`);\n pathSeparator = DEFAULT_PATH_SEPARATOR;\n }\n\n // get the tjpGib depending on what is passed in\n if (!viaTargetTjpGib) {\n if (viaMetaStoneAddr) {\n // get the tjpGib via the metastone\n viaTargetTjpGib = parseMetaStoneIb({ ib: getIbAndGib({ ibGibAddr: viaMetaStoneAddr }).ib }).tjpGib;\n } else {\n // get the tjpGib via the targetIbGibAddr\n viaTargetTjpGib = getGibInfo({ ibGibAddr: viaTargetAddr }).tjpGib;\n }\n }\n if (!viaTargetTjpGib) { throw new Error(`targetTjpGib could not be gotten. are you sure this has a tjp? or is the ibGib a stone? (E: e507f1996aaa68a229a3158b3dbc5723)`); }\n\n // build the path\n const { baseSubPath, spaceSubPath, ibgibsSubPath } = this.data!\n const tjpFullSubpath =\n `${baseSubPath}${pathSeparator}${spaceSubPath}${pathSeparator}${ibgibsSubPath}${pathSeparator}${viaTargetTjpGib}`;\n\n // return it\n return tjpFullSubpath;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion metastone related\n\n // #region other helpers\n\n /**\n * builds the path of a given file, based on params.\n *\n * ## implementation change (11/2023)\n *\n * i'm changing the implementation from a naive `subpath/ib^gib.json` approach\n * to a slightly more sophisticated one. we will change the path depending on\n * the address:\n *\n * 1. if the addr has no tjp delimiter, path will be:\n * * `(bin|dna)/[gib]/ib.json` for \"binaries\" and dna\n * * `[gib]/ib.json` for all others\n * 2. if the addr has a tjp delimiter, path will be:\n * * `[tjpGib]/[punctiliarHash]/ib.json` for all others\n * * it would be nicer to have a \"timelines\" folder but\n *\n * _NOTE: all dna and bins are stones (and have no tjpGib)._\n * _NOTE: bins may have a different extension than \"json\"._\n * _REFRESHER: punctiliarHash is the hash of a specific ibGib in time (punctiliar === point in time)._\n *\n * some benefits:\n *\n * 1. With this new structure, we can now conceivably create metastones\n * targeted at multiple levels:\n * * metastones that apply to entire timeline (tjpGib)\n * * metastones that apply to punctiliar ibGibs (punctiliarHash)\n * * metastones that apply to non-timeline stones (gib)\n * * NOTE: we atow (11/2023) are only creating metastones for\n * tracking latest punctiliar ibGibs in timelines.\n * 2. separation between meta and regular ibgibs was slightly annoying &\n * useless, as the distinction is not as clear cut as the metastone one,\n * so condensing.\n *\n * @returns the path of a given file, based on params\n */\n protected async buildPath({\n addr,\n isDna,\n isBin,\n ensureMetaStonePaths,\n pathSeparator = '/',\n pretendItsALongPath = false,\n addrIsForAMetaStone,\n }: {\n addr?: IbGibAddr,\n isDna: boolean,\n isBin?: boolean\n ensureMetaStonePaths: boolean,\n pathSeparator?: string,\n /**\n * I'm putting this in just in case the path length on the filesystem\n * changes. it will be slower, but hey, this is a rough and tough\n * implementation and they shouldn't be moving the damn folder. (*1)\n *\n * *1) just kidding. ideally we shouldn't have to worry about this kind\n * of thing but it's just an artifact of legacy os, \"time crunch\",\n * and hey I'm not a great programmer.\n */\n pretendItsALongPath?: boolean,\n /**\n * if true, the path built will be related to metastones.\n *\n * if false, the return path may still be for a metastone if the\n * incoming `addr` is itself a metastone addr.\n *\n * ## intent\n *\n * this can be because we are get/set a metastone addr or if we are\n * looking to get the directory for an address that will contain\n * metastones.\n *\n * so if either of these use cases, this should be true.\n *\n * ## notes\n *\n * * the reason for the distinction is that metastones cannot have their ibs\n * shortened because all ib information is required.\n * * perhaps in the future, i should change metastones impl to be in\n * their own folder.\n */\n addrIsForAMetaStone?: boolean,\n }): Promise<string> {\n const lc = `${this.lc}[${this.buildPath.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d630823bbe0e1a1aa3592103768e8423)`); }\n\n const data = this.data as FilesystemSpaceData_V1;\n if (!data) { throw new Error(`this.data required (E: d2553d11b637577aa7b074387b613f23)`); }\n if (!addr) { throw new Error(`addr required (E: 68149eccdbe2e6ef95eb50d588d68423)`); }\n\n let resPath: string;\n\n pathSeparator ||= '/';\n\n let { ib, gib } = getIbAndGib({ ibGibAddr: addr });\n if (!gib) { throw new Error(`gib required in building paths. if it's a primitive ibgib, then it shouldn't be put into/gotten from a space (E: 8a34bc925496c35d1892638623ec0a23)`); }\n\n // we always start from the root dir of the space subpath\n resPath = `${data.baseSubPath}${pathSeparator}${data.spaceSubPath}${pathSeparator}`;\n if (logalot) { console.log(`${lc} resPath as of space subpath: ${resPath} (I: 5feccfadec1d8ac856243e78377c1e23)`); }\n\n /**\n * store the result of isMetaStone just to keep from having to\n * call it more than once.\n */\n const addrIsAMetaStone = isMetaStone({ addr });\n // if the caller did not specify that the addr is for a metastone,\n // we still set this variable if the addr itself is a metastone.\n if (addrIsAMetaStone) { addrIsForAMetaStone = true; }\n\n // by looking at gib, determine if...\n // 1. stone (no tjp)\n // 2. tjp (gib is tjpGib b/c start of timeline)\n // 3. ibgib belongs to timeline (has tjpGib and punctiliarHash)\n\n const gibPieces = gib.split(GIB_DELIMITER);\n if (gibPieces.length === 1) {\n // either tjp, metastone, or other stone (e.g. dna).\n\n // first prefix subpath is point if dna and bin files\n if (isDna) {\n resPath += `${data.dnaSubPath}${pathSeparator}`;\n if (logalot) { console.log(`${lc} resPath dna appended subpath: ${resPath} (I: eecd26dfc1699110ae5b91dd68438f23)`); }\n } else if (isBin) {\n resPath += `${data.binSubPath}${pathSeparator}`;\n if (logalot) { console.log(`${lc} resPath bin appended subpath: ${resPath} (I: b53248d5b8d142108cf5a363f148980b)`); }\n }\n\n if (addrIsForAMetaStone || addrIsAMetaStone) {\n // we want to store the metastone in the same dir as the\n // timeline, not in the metastone's own gib dir\n let targetTjpGib: Gib;\n if (addrIsAMetaStone) {\n targetTjpGib = parseMetaStoneIb({ ib }).tjpGib;\n } else {\n const gibInfo = getGibInfo({ ibGibAddr: addr });\n targetTjpGib = gibInfo.tjpGib ?? getIbAndGib({ ibGibAddr: addr }).gib;\n }\n resPath += `${targetTjpGib}${pathSeparator}`;\n } else {\n // at this point, stones and tjps are treated the same. for\n // tjp's, their gib _is_ the tjpGib\n resPath += `${gib}${pathSeparator}`;\n }\n\n } else if (gibPieces.length === 2) {\n // belongs to a timeline\n let { tjpGib, punctiliarHash } = getGibInfo({ gib, gibDelimiter: GIB_DELIMITER });\n resPath += `${tjpGib}${pathSeparator}${punctiliarHash}${pathSeparator}`;\n } else {\n throw new Error(`invalid gib atow (11/2023). expected only one gib delimiter (${GIB_DELIMITER}) that splits two pieces of the gib, but we have ${gibPieces.length} many pieces. gib: ${gib} (E: 7d5f8608d79854e6d1d2878975258423)`);\n }\n\n // at this point, we have a full path to a directory. if this space\n // is configured to mitigate long paths and if the path is already\n // too long, then i'm not sure what to do. if it's not too long, we\n // need to check to see if it will be when we add the filename.\n\n const mitigateLongPaths = !!data.mitigateLongPaths;\n const longPathLength = data.longPathLength;\n\n /**\n * we tweak the extension for binaries (i.e. pictures like .jpg, .png,\n * etc.) in order to maintain the extension in the os's filesystem. (in\n * a future full-ibgib-os, this will be a non-issue).\n */\n let ext: string;\n\n if (isBinary({ addr })) {\n const { binExt } = getBinHashAndExt({ addr });\n ext = binExt.concat();\n } else {\n ext = 'json';\n }\n\n /**\n * filename+ext using the `ib`.\n * NOTE: if we're mitigating long paths, then we may not use this.\n */\n let filenameAsIbPlusExt: string = `${ib}.${ext}`;\n /**\n * filename+ext using the entire `addr`.\n *\n * this is used when doing meta stones (and I may change dna to use\n * this also, but if so then i need to change the path in previous\n * code).\n *\n * NOTE: if we're mitigating long paths, then we may not use this.\n */\n let filenameAsAddrPlusExt: string = `${addr}.${ext}`;\n\n if (mitigateLongPaths && longPathLength) {\n // have to take long path lengths into account\n const ameliorateLongPathMsg = ` you have to place the root folder higher up in the OS's filesystem. (and you should put in a change request to the OS to fix their weak sauce/move to/fund a better OS.) Will try what we have and hope+pray.`;\n\n if (resPath.length >= longPathLength) {\n throw new Error(`path is already too long without even having a filename. ${ameliorateLongPathMsg} (E: c126522a5cda4c2acb6de3a92fc2c423)`);\n } else if ((resPath.length + ib.length) >= longPathLength || pretendItsALongPath) {\n if (logalot) { console.warn(`${lc} the path is too long when adding the full ib as the filename (even without the ext). (W: 3011a1e58641c53274d4776f58bb5323)`); }\n if (addrIsForAMetaStone) {\n if (addrIsAMetaStone) { console.error(`can't even get a metastone ib in the path. ${ameliorateLongPathMsg} (E: 962c52deb7a5b57842c97676a1192623)`); }\n resPath += filenameAsAddrPlusExt;\n } else {\n if (logalot) { console.log(`${lc} non metastone ib found (not logging ib here for privacy). will try to shorten... (I: 73dcb3f019c9b48b92fe67a9c4f2f123)`); }\n const shorterFilenamePlusExt =\n await this.buildPath_getShorterFilenameExtSubpath_ibTooLong_nonMetaStone({\n ib, ext, pathSeparator,\n });\n resPath += shorterFilenamePlusExt;\n if (resPath.length >= longPathLength) {\n console.error(`${lc} shortened filenamePlusExt and the path is still too long. i give up. ${ameliorateLongPathMsg} (E: df9e52098b94a99212c15c167e4d9f23)`);\n }\n }\n } else {\n // the path + full ib/addr+ext is ok\n if (addrIsForAMetaStone) {\n resPath += filenameAsAddrPlusExt;\n } else {\n resPath += filenameAsIbPlusExt;\n }\n }\n } else {\n // don't need to worry about mitigating path lengths\n // the path + full ib/addr+ext is ok\n if (addrIsForAMetaStone) {\n resPath += filenameAsAddrPlusExt;\n } else {\n resPath += filenameAsIbPlusExt;\n }\n }\n\n if (logalot) { console.log(`${lc} returning resPath: ${resPath} (I: 62a76a630335a872a4fc5f25dec4b623)`); }\n\n return resPath;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * if we're here, then the path is too long with the ib.\n * we need to do a couple things:\n *\n * 1. make this deterministic\n * 2. indicate to others that may be traversing raw file system ibgib files\n * (like this one) that it has been adjusted to a long path.\n * 3. not make it too convoluted so that those same traversers can do so in\n * a reasonably straight-forward manner.\n *\n * With this given, my first implementation (atow 11/2023) will...\n *\n * 1. subpath to a \"long\" subpath (which should be a single character plus a\n * path delimiter e.g. slash).\n * * adds 1 characters + 1 slash = 2\n * 2. hash the ib and shard subpath to the first 4 chars.\n * * adds 4 characters + 1 slash = 5\n * 3. substring the ib to the first N characters\n * * atow is N = 32\n * * adds N characters + 1 dot + ext.length ~=~ N+5-ish chars. (37ish)\n *\n * This will add a total of 44-ish chars, which is less than what a\n * metastone path would be. I say this, because atow (11/2023) the code\n * execution has already checked that a metastone would be valid. So we're\n * just trying to exclude very long ib's that have e.g. 100+ characters.\n */\n protected async buildPath_getShorterFilenameExtSubpath_ibTooLong_nonMetaStone({\n ib,\n ext,\n pathSeparator,\n }: {\n ib: Ib,\n ext: string,\n pathSeparator: string,\n }): Promise<string> {\n const lc = `${this.lc}[${this.buildPath_getShorterFilenameExtSubpath_ibTooLong_nonMetaStone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1f14c5de4174d726182c5dc97bd62a23)`); }\n\n let resAdjustedFilenameExtSubpath = '';\n\n // * 1. subpath to a \"long\" subpath (which should be a single character plus a\n // * path delimiter e.g. slash).\n // * * adds 1 characters + 1 slash = 2\n let longSubPath = this.data!.longSubPath || IBGIB_LONG_SUBPATH;\n if (longSubPath.length !== 1) {\n console.warn(`${lc} longSubPath (this.data.longSubPath || IBGIB_LONG_SUBPATH) longer than one char. should be 1 char. substringing to the first char. (W: 8c19a983730f4b62ac4208f7d21c90fc)`);\n longSubPath = longSubPath.substring(0, 1) || 'l'; // l for long, get it\n }\n resAdjustedFilenameExtSubpath += `${longSubPath}${pathSeparator}`;\n\n // * 2. hash the ib and shard subpath to the first 4 chars.\n // * * adds 4 characters + 1 slash = 5\n const ibHash = await hash({ s: ib })\n const firstFourOfIbHash = ibHash.substring(0, 4);\n resAdjustedFilenameExtSubpath += `${firstFourOfIbHash}${pathSeparator}`;\n\n // * 3. substring the ib to the first N characters and add ext\n // * * atow is N = 32\n // * * adds N characters + 1 dot + ext.length ~=~ N+5-ish chars. (37ish)\n const ibSubstring = ib.substring(0, ARBITRARY_IB_SUBSTRING_LENGTH_FOR_MITIGATE_LONG_PATH);\n resAdjustedFilenameExtSubpath += `${ibSubstring}.${ext}`;\n\n return resAdjustedFilenameExtSubpath;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion other helpers\n}\n", "/**\n * @module node-filesystem-space-helper\n *\n */\n\n\nimport { readFile, } from 'node:fs/promises';\nimport { default as pathUtils } from 'path';\nimport { cwd } from 'node:process';\n\nimport { extractErrorMsg, unique, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { GIB, } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '@ibgib/core-gib/dist/core-constants.mjs';\nimport { parseSpaceIb, } from '@ibgib/core-gib/dist/witness/space/space-helper.mjs';\nimport { NodeFilesystemSpace_V1 } from './node-filesystem-space-v1.mjs';\nimport { B2TFS_DEFAULT_ENCODINGS_TO_TRY, FILE_ENCODINGS, FileDataInfo, FileEncoding } from './node-filesystem-space-types.mjs';\n\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * tries to read the given path. if fails **FOR ANY REASON**, @returns `null`.\n *\n * does not throw\n *\n * @returns file contents as string or `null`\n */\nexport async function tryRead({\n path,\n directory,\n encoding,\n}: {\n path: string,\n directory: string,\n encoding: string,\n}): Promise<string | Uint8Array | null> {\n const lc = `[${tryRead.name}]`;\n try {\n if (logalot) {\n console.log(`${lc} starting...`);\n console.log(`${lc} cwd: ${cwd()}`);\n if (path.includes('bootstrap^gib')) { console.log(`${lc} trying bootstrap^gib... (I: dacfdbe5a2d640ab947a7c17e3c56f78)`); }\n }\n const fullPath = pathUtils.join(directory, path);\n if (logalot) { console.log(`${lc} fullPath: ${fullPath} (I: 459b416ac32c711bfbab54177839b323)`); }\n encoding ||= 'utf8';\n let resRead: string | undefined = undefined;\n resRead = await readFile(fullPath, { encoding: encoding as BufferEncoding });\n\n if (logalot) {\n console.log(`${lc} record found. data length: ${resRead?.length ?? 0}. fullPath: ${fullPath}. console.dir(resRead)... (I: 82e3ad9821bd4bf8a54c8facc61dbad0)`);\n console.dir(resRead)\n }\n return resRead;\n } catch (error) {\n if (logalot) {\n console.log(`${lc} fullPath not found from directory (${directory}) and path (${path})\\nerror:\\n${extractErrorMsg(error)} (I: 1fde689d29aa47fcb589b3e7dac8929b)`);\n }\n return null;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: e2615c944a464cd48a5635fe401562d9)`); }\n }\n}\n\nexport async function tryRead_bin({\n path,\n directory,\n encoding,\n}: {\n path: string,\n directory: string,\n encoding: string,\n}): Promise<FileDataInfo | null> {\n const lc = `[${tryRead_bin.name}]`;\n try {\n if (logalot) {\n console.log(`${lc} starting...`);\n console.log(`${lc} cwd: ${cwd()}`);\n if (path.includes('bootstrap^gib')) { console.log(`${lc} trying bootstrap^gib... (I: 5eb010444b814addb1a6bbe18ca3dbfa)`); }\n }\n const fullPath = pathUtils.join(directory, path);\n if (logalot) { console.log(`${lc} fullPath: ${fullPath} (I: c342bf56df354e9ab2653855a458b99d)`); }\n encoding ||= 'utf8';\n let resRead: string | Uint8Array | undefined = undefined;\n let encodingsToTry: FileEncoding[] = unique<FileEncoding>([\n encoding as FileEncoding,\n ...FILE_ENCODINGS,\n ]);\n let { dataBuffer, dataString, inputPath, detectedEncoding } = await getFileDataAndEncoding({\n inputPath: path,\n encodingsToTry,\n });\n if (!dataBuffer) { throw new Error(`getFileDataAndEncoding yielded falsy dataBuffer (E: f7aac299212a1ae41d5bbef6079c4d24)`); }\n resRead = dataBuffer;\n\n if (logalot) {\n console.log(`${lc} record found. data length: ${resRead?.length ?? 0}. fullPath: ${fullPath}. console.dir(resRead)... (I: 438189ba2fd345d782f928ecc7dc6e58)`);\n console.dir(resRead)\n }\n\n return {\n dataBuffer, dataString, inputPath, detectedEncoding\n };\n } catch (error) {\n if (logalot) {\n console.log(`${lc} fullPath not found from directory (${directory}) and path (${path})\\nerror:\\n${extractErrorMsg(error)} (I: 882e54f079024c94864bdaa74979b397)`);\n }\n return null;\n } finally {\n if (logalot) { console.log(`${lc} complete. (I: 500e391835aa4d959adf4720fdc38c4b)`); }\n }\n}\n\n/**\n * basic validation for a node fs space ibgib\n */\nexport async function validateNodeFilesystemSpace_V1Intrinsically({ space }: { space: NodeFilesystemSpace_V1<any, any> }): Promise<string[] | null> {\n const lc = `[${validateNodeFilesystemSpace_V1Intrinsically.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: fcfe57145426ab4a5a0e961e87001922)`); }\n const errors: string[] = (await validateIbGibIntrinsically({ ibGib: space })) ?? [];\n\n const { ib, gib, data, rel8ns } = space;\n\n if (!ib) { errors.push('ib required. (E: e69ddadd947d4534ae60af9eda1bda47)'); }\n if (!gib) { errors.push('gib required. (E: 9794fb92dd79473b9139c001f0634ec2)'); }\n if (gib === GIB) { errors.push('gib cannot be primitive. (E: 651c12f1303d45aba54aa228eca1e575)'); }\n\n if (!data) {\n errors.push('data required. (E: 264d13ce6b47400e8943bf046c57e8bc)');\n return errors;\n }\n\n if (!data.name) { errors.push('space name required. (E: 4845041c9f2e44098e1e7bb30fe3c13d)') }\n // if (!data.classname) { errors.push('classname required. (E: cb645bebf8fc4baabfbf74be39563008)') }\n if (data.classname && data.classname !== NodeFilesystemSpace_V1.name) {\n errors.push(`unknown classname (${data.classname}). data.classname !== FilesystemSpace_V1.name (E: e159eb46ca5e4c2b850998af88cb5840)`);\n }\n if (!data.baseDir) { errors.push(`data.baseDir required (E: 373544741a974ab9bc0001d3d63c2601).`) }\n if (!data.baseSubPath) { errors.push(`data.baseSubPath required. (E: 7336f8eb7c7846d48993e0db893fb7cb)`) }\n if (!data.binSubPath) { errors.push(`data.binSubPath required. (E: 3544a80a3cec4fdfb35d3e6ccb36dbd6)`) }\n if (!data.dnaSubPath) { errors.push(`data.dnaSubPath required. (E: 4d6e529cdd0f47a492545c31e1dda865)`) }\n if (!data.ibgibsSubPath) { errors.push(`data.ibgibsSubPath required. (E: 11b90fdc1b1c41b492c26a61da3409b8)`) }\n if (!data.metaSubPath) { errors.push(`data.metaSubPath required. (E: 259113f4f0bc488785f9019160c8a226)`) }\n if (data.n && typeof data.n !== 'number') { errors.push(`data.n must be a number. (E: e7c76f44b1114dba949d06146a8c169b)`) }\n if (data.n === undefined) {\n // the very first space record (tjp) has an undefined n and no rel8ns\n if (rel8ns) { errors.push(`rel8ns not expected when data.n is falsy (custom temporal junction point indicator I suppose...) (E: 08604c8b33524009886ac2c63eb34c50)`); }\n }\n if (!data.spaceSubPath) { errors.push(`data.spaceSubPath required. (E: 1688a59dfc6447b3bccb7690b233e4fa)`) }\n if (!data.uuid) { errors.push(`data.uuid required. (E: dd984a04d0d14d16a4faa300ec125960)`) }\n if (!data.encoding) { errors.push(`data.encoding required. (E: e75958932f614364a1765a875acad2ce)`) }\n /** should probably get this from Capacitor... */\n const validEncodings = [\"utf8\", \"ascii\", \"utf16\"];\n if (!validEncodings.includes(data.encoding)) {\n errors.push(`invalid encoding: ${data.encoding}. validEncodings: ${validEncodings.join(', ')} (E: b88b909521db42cbae684c2937c77079)`);\n }\n\n // ensure ib matches up with internal data\n const { spaceClassname, spaceId, spaceName } = parseSpaceIb({ spaceIb: ib });\n if (data.classname && (spaceClassname !== data.classname)) {\n errors.push(`ib's spaceClassname (${spaceClassname}) must match data.classname (${data.classname}) (E: 913b8b98717647fea832e4cca80d8ee6)`);\n }\n if (spaceId !== data.uuid) {\n errors.push(`ib's spaceId (${spaceId}) must match data.uuid (${data.uuid}) (E: b20f36f32bc244008b4df856f892a62a)`);\n }\n if (spaceName !== data.name) {\n errors.push(`ib's spaceName (${spaceName}) must match data.name (${data.name}) (E: cf599a9bf875464d9ec99c79cdee0452)`);\n }\n\n // ensure rel8ns make sense\n if (data.n === undefined && (rel8ns?.past ?? []).length > 0) {\n errors.push(`\"past\" rel8n not expected when data.n is falsy (E: 77bb7a90b40a4d989a9e53053776be86)`);\n }\n if (data.n && (rel8ns?.past ?? []).length === 0) {\n errors.push(`\"past\" rel8n required when data.n is truthy (E: 735e07bac58b44deb2523e3d349d5479)`);\n }\n if (data.n === 0 && (rel8ns?.past ?? []).length !== 1) {\n errors.push(`\"past\" rel8n expected to have a single record when data.n === 0 (E: 8915bb8084414d3b810cff9bccfc3ec6)`);\n }\n if (rel8ns && (rel8ns.past?.length ?? -1) > 0) {\n const pastAddrs = rel8ns.past as IbGibAddr[];\n pastAddrs.forEach(x => {\n const { ib: pastIb } = getIbAndGib({ ibGibAddr: x });\n const pastIbInfo = parseSpaceIb({ spaceIb: pastIb });\n if (pastIbInfo.spaceClassname && (pastIbInfo.spaceClassname !== spaceClassname)) {\n errors.push(`rel8ns.past address classname (${pastIbInfo.spaceClassname}) must match current spaceClassname (${spaceClassname}) (E: 10b2f05597574558ad2f20db8e471a44)`);\n }\n if (pastIbInfo.spaceId !== spaceId) {\n errors.push(`rel8ns.past address spaceId (${pastIbInfo.spaceId}) must match current spaceId (${spaceId}) (E: 78b665a31fc34c68be3884d4cd4da35a)`);\n }\n // i want to allow this, but for now we're going to require not changing the name...\n if (pastIbInfo.spaceName !== spaceName) {\n errors.push(`rel8ns.past address spaceName (${pastIbInfo.spaceName}) must match current spaceName (${spaceName}) (E: 8a6621cbec9e48e7b6d880375c444bfe)`);\n }\n });\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * gets the data and encoding of a given {@link inputPath} if that file exists.\n * if it doesn't exist, this will throw an ENOENT error, but this is not logged\n * as an error.\n *\n * this is because atow (03/2024) this is only used in a tryRead_bin function\n * where the file often does not exist.\n */\nexport async function getFileDataAndEncoding({\n inputPath,\n encodingsToTry = B2TFS_DEFAULT_ENCODINGS_TO_TRY,\n}: {\n inputPath: string,\n encodingsToTry?: (FileEncoding | undefined)[],\n}): Promise<FileDataInfo> {\n const lc = `[${getFileDataAndEncoding.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b4688e6e5f28efa9ed95729f10a6df24)`); }\n\n let resDataAndEncoding: FileDataInfo | undefined = undefined;\n const dataBuffer = await readFile(inputPath);\n\n if (dataBuffer.length === 0) {\n console.warn(`${lc} file at inputPath (${inputPath}) has dataBuffer.length === 0, i.e., no data content. we are treating this as utf8. (W: 2ea55367538146d695482cfb6ec1b79a)`)\n return {\n inputPath,\n dataBuffer,\n detectedEncoding: 'utf8',\n dataString: '',\n }; /* <<<< returns early */\n }\n\n encodingsToTry ??= B2TFS_DEFAULT_ENCODINGS_TO_TRY;\n\n const tryEncoding = async (encoding: FileEncoding | undefined) => {\n let res: [boolean, string | undefined];\n try {\n const str = dataBuffer.toString(encoding ?? undefined);\n /**\n * doesn't include the node.js replacement unicode char\n */\n const isProbablyCorrect = !str.includes('\\ufffd');\n res = [isProbablyCorrect, str];\n return res;\n } catch (error) {\n debugger;\n res = [false, undefined];\n }\n return res;\n }\n\n for (let i = 0; i < encodingsToTry.length; i++) {\n const maybeEncoding = encodingsToTry[i];\n const [isProbablyCorrectEncoding, dataString] = await tryEncoding(maybeEncoding);\n if (isProbablyCorrectEncoding) {\n resDataAndEncoding = {\n inputPath,\n dataString,\n detectedEncoding: maybeEncoding,\n dataBuffer,\n };\n break;\n }\n }\n\n if (!resDataAndEncoding) {\n debugger; // !resDataAndEncoding -> want to see why resDataAndEncoding is still undefined\n throw new Error(`couldn't turn dataBuffer (length: ${dataBuffer.length}) into dataString with encodingsToTry: (${encodingsToTry}). no idea why. (E: 557c7722f2df7703429778662d3ea224)`);\n // resDataAndEncoding = {\n // inputPath,\n // detectedEncoding: undefined,\n // dataString: undefined,\n // dataBuffer,\n // }\n }\n\n return resDataAndEncoding;\n } catch (error) {\n // i'm just suppressing ENOENT at this time because in context, this is\n // often the case. we do, however, rethrow the error for proper flow.\n const emsg = extractErrorMsg(error);\n if (!emsg.startsWith('ENOENT:')) { console.error(`${lc} ${emsg}`); }\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "/**\n * @module node-filesystem-space-types\n *\n * mostly interfaces, some constants\n */\n\nimport { IbGibRel8ns_V1, } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS, IBGIB_SPACE_NAME_DEFAULT, ZERO_SPACE_ID } from '@ibgib/core-gib/dist/witness/space/space-constants.mjs';\nimport {\n IBGIB_BASE_SUBPATH, IBGIB_SPACE_SUBPATH_DEFAULT, IBGIB_BASE_DIR,\n IBGIB_ENCODING, IBGIB_IBGIBS_SUBPATH, IBGIB_META_SUBPATH,\n IBGIB_BIN_SUBPATH, IBGIB_DNA_SUBPATH,\n IBGIB_LONG_SUBPATH,\n DEFAULT_LONG_PATH_LENGTH,\n DEFAULT_FILESYSTEM_SPACE_DESCRIPTION,\n} from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';\nimport {\n FilesystemSpaceData_V1,\n FilesystemSpaceOptionsData, FilesystemSpaceOptionsRel8ns, FilesystemSpaceOptionsIbGib,\n FilesystemSpaceResultData, FilesystemSpaceResultRel8ns, FilesystemSpaceResultIbGib,\n} from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-space-v1.mjs';\n\n\n/**\n * This is the shape of data about this space itself (not the contained ibgibs' spaces).\n */\nexport interface NodeFilesystemSpaceData_V1 extends FilesystemSpaceData_V1 {\n}\n\n/**\n * Used in bootstrapping.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_NODE_FILESYSTEM_SPACE_DATA_V1: NodeFilesystemSpaceData_V1 = {\n version: '2',\n uuid: ZERO_SPACE_ID,\n name: IBGIB_SPACE_NAME_DEFAULT,\n classname: 'NodeFilesystemSpace_V1',\n baseDir: IBGIB_BASE_DIR,\n encoding: IBGIB_ENCODING,\n baseSubPath: IBGIB_BASE_SUBPATH,\n spaceSubPath: IBGIB_SPACE_SUBPATH_DEFAULT,\n ibgibsSubPath: IBGIB_IBGIBS_SUBPATH,\n metaSubPath: IBGIB_META_SUBPATH,\n binSubPath: IBGIB_BIN_SUBPATH,\n dnaSubPath: IBGIB_DNA_SUBPATH,\n longSubPath: IBGIB_LONG_SUBPATH,\n mitigateLongPaths: true,\n longPathLength: DEFAULT_LONG_PATH_LENGTH,\n persistOptsAndResultIbGibs: false,\n validateIbGibAddrsMatchIbGibs: false,\n longPollingIntervalMs: DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,\n allowPrimitiveArgs: false,\n catchAllErrors: true,\n description: DEFAULT_FILESYSTEM_SPACE_DESCRIPTION,\n trace: false,\n}\n\n/** Marker interface atm */\nexport interface NodeFilesystemSpaceRel8ns_V1 extends IbGibRel8ns_V1 { }\n\n/**\n * Space options involve whether we're getting/putting ibgibs categorized as\n * meta, bin, dna.\n *\n * We'll leverage the fact that we don't need to get dna very often, and that\n * meta ibgibs act differently and are recorded differently.\n *\n * For example, we don't necessarily want to keep the past of certain meta\n * objects, because it may change (and thus grow) too quickly.\n */\nexport interface NodeFilesystemSpaceOptionsData extends FilesystemSpaceOptionsData {\n}\n\nexport interface NodeFilesystemSpaceOptionsRel8ns extends FilesystemSpaceOptionsRel8ns {\n}\n\n/** Marker interface atm */\nexport interface NodeFilesystemSpaceOptionsIbGib\n extends FilesystemSpaceOptionsIbGib<NodeFilesystemSpaceOptionsData, NodeFilesystemSpaceOptionsRel8ns> {\n}\n\n/** Marker interface atm */\nexport interface NodeFilesystemSpaceResultData extends FilesystemSpaceResultData {\n}\n\nexport interface NodeFilesystemSpaceResultRel8ns extends FilesystemSpaceResultRel8ns {\n}\n\nexport interface NodeFilesystemSpaceResultIbGib\n extends FilesystemSpaceResultIbGib<NodeFilesystemSpaceResultData, NodeFilesystemSpaceResultRel8ns> {\n}\n/**\n * currently i'm just taking this from the definition of node's `Buffer` type.\n *\n * ## notes\n *\n * * using this with handle-reify-file.mts when reading the file.\n * * 'binary' may resolve to 'latin1' per SO\n * * https://stackoverflow.com/questions/46441667/reading-binary-data-in-node-js\n */\nexport type FileEncoding =\n | 'ascii'\n | 'utf8'\n | 'utf-8'\n | 'utf16le'\n | 'ucs2'\n | 'ucs-2'\n | 'base64'\n | 'base64url'\n | 'latin1'\n | 'binary'\n | 'hex';\nexport const FileEncoding = {\n ascii: 'ascii' as FileEncoding,\n utf8: 'utf8' as FileEncoding,\n utf_8: 'utf-8' as FileEncoding,\n ['utf-8']: 'utf-8' as FileEncoding,\n utf16le: 'utf16le' as FileEncoding,\n ucs2: 'ucs2' as FileEncoding,\n ucs_2: 'ucs-2' as FileEncoding,\n ['ucs-2']: 'ucs-2' as FileEncoding,\n base64: 'base64' as FileEncoding,\n base64url: 'base64url' as FileEncoding,\n latin1: 'latin1' as FileEncoding,\n binary: 'binary' as FileEncoding,\n hex: 'hex' as FileEncoding,\n};\n/**\n * valid file encoding values per {@link FileEncoding}\n */\nexport const FILE_ENCODINGS = Object.values(FileEncoding);\n\nexport interface FileDataInfo {\n inputPath: string;\n detectedEncoding?: FileEncoding | undefined;\n dataString?: string | undefined;\n dataBuffer?: Uint8Array | undefined;\n}\nexport const B2TFS_DEFAULT_ENCODINGS_TO_TRY: (FileEncoding | undefined)[] = [\n FileEncoding.utf8,\n FileEncoding.utf16le,\n FileEncoding.base64,\n FileEncoding.binary,\n undefined,\n];\n", "/**\n * @module node-indexed-filesystem-space-constants\n */\n\n\nexport const DEFAULT_INDEXED_FILESYSTEM_SPACE_DESCRIPTION = `This is an indexed-based filesystem space. The ibgib data contains settings for the space itself, and the witness ibgib object interfaces with a back end that is hierarchical like a filesystem. This uses a custom indexing system to shorten path lengths.`;", "/**\n * @module node-indexed-filesystem-space-types\n */\n\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport {\n NodeFilesystemSpaceData_V1,\n NodeFilesystemSpaceRel8ns_V1,\n} from '../node-filesystem-space-types.mjs';\nimport { DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS, IBGIB_SPACE_NAME_DEFAULT, ZERO_SPACE_ID } from '@ibgib/core-gib/dist/witness/space/space-constants.mjs';\nimport {\n DEFAULT_LONG_PATH_LENGTH, IBGIB_BASE_DIR, IBGIB_BASE_SUBPATH,\n IBGIB_BIN_SUBPATH, IBGIB_DNA_SUBPATH, IBGIB_ENCODING, IBGIB_IBGIBS_SUBPATH,\n IBGIB_LONG_SUBPATH, IBGIB_META_SUBPATH, IBGIB_SPACE_SUBPATH_DEFAULT\n} from '@ibgib/core-gib/dist/witness/space/filesystem-space/filesystem-constants.mjs';\nimport { DEFAULT_INDEXED_FILESYSTEM_SPACE_DESCRIPTION } from './node-indexed-filesystem-space-constants.mjs';\n\n/**\n * Data for indexed filesystem space.\n */\nexport interface NodeIndexedFilesystemSpaceData_V1 extends NodeFilesystemSpaceData_V1 {\n}\n\n/**\n * Rel8ns for indexed filesystem space.\n */\nexport interface NodeIndexedFilesystemSpaceRel8ns_V1 extends NodeFilesystemSpaceRel8ns_V1 {\n}\n\n/**\n * IbGib representing the indexed filesystem space.\n * Does not descend from a NodeFilesystemSpace ibgib type, just the base IbGib_V1.\n */\nexport interface NodeIndexedFilesystemSpaceIbGib_V1\n extends IbGib_V1<NodeIndexedFilesystemSpaceData_V1, NodeIndexedFilesystemSpaceRel8ns_V1> {\n}\n\n/**\n * Used in bootstrapping.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_NODE_INDEXED_FILESYSTEM_SPACE_DATA_V1: NodeIndexedFilesystemSpaceData_V1 = {\n version: '2',\n uuid: ZERO_SPACE_ID,\n name: IBGIB_SPACE_NAME_DEFAULT,\n classname: 'NodeIndexedFilesystemSpace_V1',\n baseDir: IBGIB_BASE_DIR,\n encoding: IBGIB_ENCODING,\n baseSubPath: IBGIB_BASE_SUBPATH,\n spaceSubPath: IBGIB_SPACE_SUBPATH_DEFAULT,\n ibgibsSubPath: IBGIB_IBGIBS_SUBPATH,\n metaSubPath: IBGIB_META_SUBPATH,\n binSubPath: IBGIB_BIN_SUBPATH,\n dnaSubPath: IBGIB_DNA_SUBPATH,\n longSubPath: IBGIB_LONG_SUBPATH,\n mitigateLongPaths: false,\n longPathLength: DEFAULT_LONG_PATH_LENGTH,\n persistOptsAndResultIbGibs: false,\n validateIbGibAddrsMatchIbGibs: false,\n longPollingIntervalMs: DEFAULT_LOCAL_SPACE_POLLING_INTERVAL_MS,\n allowPrimitiveArgs: false,\n catchAllErrors: true,\n description: DEFAULT_INDEXED_FILESYSTEM_SPACE_DESCRIPTION,\n trace: false,\n}", "export const GLOBAL_LOG_A_LOT = false;\r\nexport const GLOBAL_TIMER_NAME = '[space^gib server timer]';", "/**\n * @module outer-space\n * Outer spaces are spaces connecting local inner spaces.\n * ATOW there is just sync spaces, but definitely just the beginning.\n *\n * ## on future implementations, CRDT-like behavior\n *\n * I just realized that when merging, I can actually create a meta transform\n * ibgib to maintain the order of transforms.\n */\n\nimport { IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\nimport { IbGibAddr, IbGib, Gib, Ib, } from '@ibgib/ts-gib/dist/types.mjs';\n\nimport {\n IbGibSpaceData, IbGibSpaceRel8ns,\n IbGibSpaceOptionsData, IbGibSpaceOptionsRel8ns, IbGibSpaceOptionsIbGib,\n IbGibSpaceOptionsCmdModifier,\n IbGibSpaceResultData, IbGibSpaceResultRel8ns, IbGibSpaceResultIbGib, SyncSpaceSubtype, SpaceType, SpaceSubtype,\n} from '../space-types.mjs';\nimport { IbGibSpaceAny } from '../space-base-v1.mjs';\nimport { CIPHERTEXT_REL8N_NAME } from '../../../common/encrypt/encrypt-constants.mjs';\nimport { SubjectWitness } from '../../../common/pubsub/subject/subject-types.mjs';\nimport { SubscriptionWitness } from '../../../common/pubsub/subscription/subscription-types.mjs';\n\n/**\n * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n *\n * ## driving use case\n *\n * I'm adding this for tracking status for longer-running inter-spatial\n * communications. Specifically, I'm working on the first aws dynamo db\n * sync space.\n *\n * ## notes\n *\n * * I think http status codes do a pretty good job of protocol information\n * exchange.\n * * The only non-standard status code I'm doing ATOW is 0 meaning \"undefined\".\n * * I'm adding (whitelisting) codes as I use them.\n * * Note that sections of code check for validation of membership here and\n * will error if not present.\n */\nexport type StatusCode =\n 'undefined' |\n 'preparing' |\n 'started' |\n 'inserted' | 'updated' |\n 'merged_dna' | 'merged_state' |\n 'already_synced' |\n 'completed';\nexport const StatusCode = {\n /**\n * Using this as the code for the parent primitive.\n */\n undefined: 'undefined' as StatusCode,\n /**\n * gt\n */\n preparing: 'preparing' as StatusCode,\n /**\n * Communication between spaces has just started, but no evaluation as to\n * intrinsic ibgibs shared has been made.\n *\n * Using this for the start of the sync process, meaning the ball has begun\n * rolling, a metadata ibgib to track the operation has been created (but\n * not necessarily yet stored), but no intrinsic (non-meta) data has been\n * exchanged.\n */\n started: 'started' as StatusCode,\n /**\n * New insertion of ibgib(s) into the outerspace.\n *\n * The outerspace did not have the timeline or ibgib(s) at all, so this is\n * the first time.\n */\n inserted: 'inserted' as StatusCode,\n /**\n * Updated outerspace with local ibgib(s).\n *\n * The outerspace had the same timeline as the local space, just not as\n * recent.\n */\n updated: 'updated' as StatusCode,\n /**\n * When syncing, this means that we've reconciled one or more timeline(s)\n * between the local and sync spaces. The process of this was by\n * automatically applying dna ibgibs that did not exist in one or the other\n * timelines, so that the end result is that the dna at the end is\n * \"effectively equal\". this does not guarantee order, it only guarantees\n * application. anything sensitive to order must be done with locality.\n *\n * Note that in this case, we've created new ibgib to fulfill the operation\n * (besides the derivative metadata ibgibs created in the communication).\n * These ibgibs should be found on the status ibgib.\n *\n * @see {@link merged_state}\n */\n merged_dna: 'merged_dna' as StatusCode,\n /**\n * Similar to {@link merged_dna}, but we didn't have dna to work with. So we\n * fudged and did our best guess at merging the state using some opinionated\n * algorithms.\n *\n * Note that in this case, we've created new ibgib to fulfill the operation\n * (besides the derivative metadata ibgibs created in the communication).\n * These ibgibs should be found on the status ibgib.\n *\n * @see {@link merged_dna}\n */\n merged_state: 'merged_state' as StatusCode,\n /**\n * The operation has completed, but there were no intrinsic changes.\n *\n * For example, if we were to sync an ibGib but it's already up-to-date in a\n * space, then we have generated metadata ibgibs. But *intrinsically* we have\n * not altered any timeline ibgibs or added any stone ibgibs.\n */\n already_synced: 'already_synced' as StatusCode,\n /**\n * Inter-spatial communication complete.\n *\n * * There should be no more status updates after this.\n * * syncStatus$ observable should be completed just after this.\n * * subscribers should unsubscribe if not already done.\n * * I think this happens at the publishing end also, but always good\n * to take care of your own cleanup if possible.\n *\n */\n completed: 'completed' as StatusCode,\n}\n\nexport interface OuterSpaceData extends IbGibSpaceData {\n}\n\nexport interface OuterSpaceRel8ns extends IbGibSpaceRel8ns {\n /**\n * the ciphertext will contain private data that is typed per use case (per\n * concrete implementation).\n */\n [CIPHERTEXT_REL8N_NAME]?: IbGibAddr[];\n}\n\n/**\n *\n */\nexport interface OuterSpaceIbGib\n extends IbGib_V1<OuterSpaceData, OuterSpaceRel8ns> {\n}\n\nexport interface SyncSpaceData extends OuterSpaceData {\n type: 'sync';\n subtype: SyncSpaceSubtype;\n /**\n * if true, this sync space will NOT store status updates **IN THE SYNC\n * SPACE** as the sync saga progresses.\n *\n * the **local space** will still store the status ibgib updates.\n *\n * ## notes\n *\n * ideally, it would be useful to always store status updates in order to\n * see the history of the transaction. in the future we will have an expiry\n * or ttl. another option is to have this setting configurable from the\n * calling function, or more complex participant requirements. for now we\n * have this stopgap boolean flag.\n *\n * ## intent\n *\n * i want to be able to run tests against aws that are less expensive, as\n * long as we are ultimately testing both...\n *\n * 1. storing status updates\n * * preferable for auditing/debugging and long-term cost reduction\n * 2. not storing status updates\n * * preferable for short-term performance and short-term cost reduction\n *\n * @default should be false\n */\n dontStoreStatusUpdatesInSyncSpace: boolean;\n}\nexport interface SyncSpaceRel8ns extends OuterSpaceRel8ns {\n}\nexport interface SyncSpaceIbGib\n extends IbGib_V1<SyncSpaceData, SyncSpaceRel8ns> {\n}\n\n/**\n * this is the info about the **space**, as in the space participates in the\n * synchronization saga.\n */\nexport interface ParticipantInfo {\n /**\n * space.data.uuid\n */\n id: string;\n /**\n * space's gib\n */\n gib: Gib;\n /**\n * s = src, d = destination\n *\n * so this is discriminator of source or destination in terms of the\n * participant's role.\n */\n s_d: 'src' | 'dest';\n}\n\n/**\n * Options shape specific to OuterSpaces.\n * Marker interface only atm.\n */\nexport interface OuterSpaceOptionsData extends IbGibSpaceOptionsData {\n /**\n * Operation id across multiple spaces.\n *\n * ## notes\n *\n * If src/local space is communicating with more than one\n * other space, then this can be used to coordinate among\n * all of them. If there are only two spaces, then the\n * gib of the individual status ibgib is just as uniquely\n * identifying.\n */\n multiSpaceOpId?: string;\n /**\n * Modifying flags for cmd routing for the associated cmd ibGib.\n */\n cmdModifiers?: (OuterSpaceOptionsCmdModifier | string)[];\n /**\n * This id is used when communicating between two spaces. During that\n * communication, multiple ibgibs will be passed back and forth, and this\n * `sagaId` will be common among those messages.\n *\n * There is also an id that is common to operations that\n * refer to multiple spaces. {@see multiSpaceOpId}\n */\n sagaId?: string;\n /**\n * Info of the participating spaces (as endpoints) in the communication.\n */\n participants?: ParticipantInfo[];\n}\n\nexport interface OuterSpaceOptionsRel8ns extends IbGibSpaceOptionsRel8ns {\n}\nexport interface OuterSpaceOptionsIbGib<\n TIbGib extends IbGib = IbGib_V1,\n TOptsData extends OuterSpaceOptionsData = OuterSpaceOptionsData,\n // TOptsRel8ns extends IbGibSpaceOptionsRel8ns = IbGibSpaceOptionsRel8ns\n TOptsRel8ns extends OuterSpaceOptionsRel8ns = OuterSpaceOptionsRel8ns,\n> extends IbGibSpaceOptionsIbGib<TIbGib, TOptsData, TOptsRel8ns> {\n}\n\nexport interface OuterSpaceResultData extends IbGibSpaceResultData {\n /**\n * If the space operation involves a saga, this is the id.\n */\n sagaId?: string;\n}\nexport interface OuterSpaceResultRel8ns extends IbGibSpaceResultRel8ns {\n}\nexport interface OuterSpaceResultIbGib<\n TIbGib extends IbGib,\n TResultData extends OuterSpaceResultData,\n TResultRel8ns extends OuterSpaceResultRel8ns\n> extends IbGibSpaceResultIbGib<TIbGib, TResultData, TResultRel8ns> {\n}\n\n/**\n * Marker atm.\n *\n * {@see IbGibSpaceOptionsCmdModifier}\n */\nexport type OuterSpaceOptionsCmdModifier = IbGibSpaceOptionsCmdModifier;\n/**\n * Marker atm.\n *\n * {@see IbGibSpaceOptionsCmdModifier}\n */\nexport const OuterSpaceOptionsCmdModifier = {\n ...IbGibSpaceOptionsCmdModifier,\n}\n\n/**\n * Extends basic ibgib space options cmd modifiers to include sync specific ones.\n *\n * {@see IbGibSpaceOptionsCmdModifier}\n * {@see OuterSpaceOptionsCmdModifier}\n */\nexport type SyncSpaceOptionsCmdModifier = OuterSpaceOptionsCmdModifier | 'sync';\n/**\n * Flags to affect the command's interpretation.\n *\n * {@see IbGibSpaceOptionsCmdModifier}\n * {@see OuterSpaceOptionsCmdModifier}\n */\nexport const SyncSpaceOptionsCmdModifier = {\n ...OuterSpaceOptionsCmdModifier, // \"inherited\"\n /**\n * special type of 'put' operation that will start a sync process.\n */\n sync: 'sync' as SyncSpaceOptionsCmdModifier,\n}\n\nexport interface SyncSpaceOptionsData extends OuterSpaceOptionsData {\n /**\n * Extends inherited\n */\n cmdModifiers?: (SyncSpaceOptionsCmdModifier | string)[];\n /**\n * Each Sync has a status ibGib that tracks the progress of the\n * overall sync operation (saga).\n *\n *\n * If this is specified, then it means the sync cmd is associated with\n * an existing/ongoing operation.\n */\n tjpGib?: Gib;\n // txId?: string;\n /**\n * tjp addrs of all timelines that are to be synced in the sync transaction.\n */\n ibGibAddrs_All_Tjps?: IbGibAddr[];\n /**\n * all addrs of non-tjp (stones) that are to be synced.\n *\n * this is essentially a replication process, i.e., either it has it or it\n * doesn't.\n */\n ibGibAddrs_All_NonTjps?: IbGibAddr[];\n}\nexport interface SyncSpaceOptionsRel8ns extends OuterSpaceOptionsRel8ns {\n}\n/**\n * options ibgib (argument ibgib) sent to a sync space.\n */\nexport interface SyncSpaceOptionsIbGib<\n TIbGib extends IbGib = IbGib_V1,\n TOptsData extends SyncSpaceOptionsData = SyncSpaceOptionsData,\n TOptsRel8ns extends SyncSpaceOptionsRel8ns = SyncSpaceOptionsRel8ns,\n> extends OuterSpaceOptionsIbGib<TIbGib, TOptsData, TOptsRel8ns> {\n /**\n * Produces status ibgibs or error strings.\n */\n syncSagaInfo: SyncSagaInfo;\n}\n\nexport interface SyncSpaceResultData extends OuterSpaceResultData {\n statusTjpAddr?: IbGibAddr;\n}\nexport interface SyncSpaceResultRel8ns extends OuterSpaceResultRel8ns {\n}\n/**\n * result ibgib (return) from a syncspace.witness(syncOptionsIbGib) call.\n */\nexport interface SyncSpaceResultIbGib<\n TIbGib extends IbGib = IbGib_V1,\n TResultData extends SyncSpaceResultData = SyncSpaceResultData,\n TResultRel8ns extends SyncSpaceResultRel8ns = SyncSpaceResultRel8ns\n> extends OuterSpaceResultIbGib<TIbGib, TResultData, TResultRel8ns> {\n /**\n * Produces status ibgibs or error strings.\n */\n syncSagaInfo: SyncSagaInfo;\n}\n\n/**\n * status info on the sync process.\n */\nexport interface SyncStatusData {\n /**\n * Status code for this status update.\n *\n * Note that this is also in the ib, which will be in each of the\n * statuses' `past` rel8n. This way, callers can easily tell which\n * kinds of actions were required.\n */\n statusCode: StatusCode;\n\n // /**\n // * unused?\n // */\n // syncGib: string;\n\n // srcSpaceId: string;\n // srcSpaceGib: string;\n participants: ParticipantInfo[];\n\n /**\n * Explicit re-declaration from base data, just to remind us...I guess...\n *\n * This indicates if this status ibgib is the tjp for the status line.\n */\n isTjp?: boolean;\n\n /**\n * When putting, this is the list of ibGibs to send.\n *\n * ## notes\n *\n * Maybe the receiver needs all of these, maybe it doesn't.\n */\n toTx?: IbGibAddr[];\n /**\n * When putting, this is the list of ibGibs we don't need/want (or refuse)\n * to send.\n *\n * IGNORED ATOW\n *\n * ## notes\n *\n * Not really sure about this atow, since the aws-dynamo space is not a true\n * communication between two separate nodes. Just figure someone will have a\n * reason for it in the future.\n */\n notToTx?: IbGibAddr[];\n /**\n * When communicating, the receiver is asking the sender for\n * these ibGibs.\n *\n * ## notes\n *\n * ATOW this indicates only that the receiver does not have\n * these addresses.\n */\n toRx?: IbGibAddr[];\n /**\n * A receiving space can set this to indicate to the transmitter that it\n * does not need/want these, possibly because they already have them or just\n * are not interested in them.\n *\n * ## notes\n *\n * ATOW this will only be because the receiver already has these addresses.\n */\n notToRx?: IbGibAddr[];\n\n /**\n * Flag to indicate that THIS STEP in communication (part of a saga) had no\n * errors.\n */\n success?: boolean;\n\n /**\n * If this is true, then the tx/rx inter-space saga is marked\n * as complete and this status ibgib should be the last one.\n */\n complete?: boolean;\n /**\n * List of warnings for THIS STEP in the inter-spatial communication.\n *\n * Should NOT be an accumulating list of warnings, i.e., if a warning\n * happens early on in a tx/rx, then it stays on that ibGib.\n */\n warnings?: string[];\n /**\n * List of errors for THIS STEP in the inter-spatial communication.\n *\n * Should NOT be an accumulating list of errors, i.e., if an error happens\n * early on in a tx/rx, then it stays on that ibGib.\n *\n * ## notes\n *\n * atow my error workflow is pretty minimal. So I think if any error happens\n * the entire saga gets nixed...\n *\n * But it should be that this type of behavior should be determined by\n * on-chain ibgibs that correspond to consensus behavior contracts (with a\n * default behavior ultimately existing hard-coded in source).\n */\n errors?: string[];\n\n /**\n * List of ibgib addrs that were newly created specifically for this\n * space operation.\n *\n * ATOW, this means that there was a merged timeline event and\n * the receiving space dynamically applied dna to its existing\n * timeline.\n *\n * ## notes\n *\n * * This should not include status metadata ibgibs, as this is\n * already captured in the `past` rel8n.\n */\n didCreate?: IbGibAddr[];\n /**\n * List of ibgib addrs that were merged in the rx space instead of stored\n * directly.\n *\n * Tx space may choose to somehow mark these as orphaned or whatever seems\n * best per use case. (i.e. I haven't coded that yet even in this naive\n * first implementation)\n */\n didMergeMap?: { [oldAddr: string]: IbGibAddr };\n /**\n * List of ibgibs that were actively transmitted to the receiving\n * space.\n *\n * ## notes\n *\n * * It could be that the receiving space received the ibgib,\n * but that it already had it. It may have been unsure if it\n * had it based on the algorithms in play.\n * * An empty array upon completion of a communication saga\n * indicates that the receiving space already had all of the\n * ibgibs attempted to be sent, i.e., it was already up-to-date.\n *\n */\n didRx?: IbGibAddr[];\n /**\n * List of ibgibs that were actively transmitted from the receiving\n * space to the sending space.\n *\n * ## notes\n *\n * * During a sync operation, any ibgibs that start in the sync space\n * and are \"sent\" to the local space during the sync operation that\n * did not originate from the local space will be here.\n */\n didTx?: IbGibAddr[];\n}\n\nexport interface SyncStatusRel8ns extends IbGibRel8ns_V1 {\n created?: IbGibAddr[];\n final?: IbGibAddr[];\n}\n\n/**\n * IbGib that tracks/logs the entire syncing process.\n *\n * Since this is created with a tjp, it includes the tjp.gib in\n * each status frame ibgib.gib. This tjp.gib acts as the \"saga id\"\n * or \"status stream id\".\n *\n * ## stages\n *\n * ### starting - (code 102)\n *\n * Gets the ball rolling with creating the first status ibgib.\n *\n * ###\n *\n */\nexport interface SyncStatusIbGib extends IbGib_V1<SyncStatusData, SyncStatusRel8ns> {\n statusIbGibGraph: IbGib_V1[],\n /**\n * Ibgibs that were created as side effects from a merge.\n *\n * ## notes\n *\n * This happens when you apply one or more local transforms to\n * a timeline in the store that has already been changed by some\n * other space (other than local that is).\n */\n createdIbGibs?: IbGib_V1[];\n /**\n * Ibgibs that are only found in the store and not locally.\n *\n * ## notes\n *\n * This happens when ibgibs were created in some other space.\n */\n storeOnlyIbGibs?: IbGib_V1[];\n /**\n * This is a map of the local space \"oldAddr\" to the ultimately\n * most recent ibgib address in the outer/sync space.\n *\n * ## notes\n *\n * You will need to also download the createdIbGibs and/or storeOnlyIbGibs\n * which will contain the dependency graph between these two endpoints in\n * each map entry here from old addr -> new addr.\n *\n * It is assumed that the local address already has all of the rest of the\n * dependencies for `oldAddr`.\n */\n ibGibsMergeMap?: { [oldAddr: string]: IbGib_V1 };\n}\n\n/**\n * A saga atow refers only to the saga across a single space.\n */\nexport interface SagaInfo<\n TIbGib extends IbGib_V1,\n TSpaceOptionsData extends OuterSpaceOptionsData,\n TSpaceOptionsRel8ns extends OuterSpaceOptionsRel8ns,\n TSpaceOptionsIbGib extends OuterSpaceOptionsIbGib<TIbGib, TSpaceOptionsData, TSpaceOptionsRel8ns>,\n TSpaceResultData extends OuterSpaceResultData,\n TSpaceResultRel8ns extends OuterSpaceResultRel8ns,\n TSpaceResultIbGib extends OuterSpaceResultIbGib<TIbGib, TSpaceResultData, TSpaceResultRel8ns>,\n TStatusIbGib extends TIbGib,\n> {\n /**\n * UUID generated at the beginning of a multi-space operation that is common\n * across all spaces.\n *\n * This is in contrast with a `sagaId`, which only pertains to a saga within\n * a single space.\n */\n multiSpaceOpId: string;\n /**\n * UUID generated at the beginning of a sync saga for a single space.\n *\n * This is in contrast with the `syncId`, which pertains to a sync operation\n * across all spaces.\n */\n sagaId: string;\n /**\n * Reference to the space with which we're communicating.\n *\n * Note that this is a witness not just an ibgib data shape. so you will be\n * able to pass in args to witness to this space.\n */\n outerSpace: IbGibSpaceAny;\n spaceId: string;\n participants: ParticipantInfo[];\n\n complete?: boolean;\n\n /**\n * Only publishes values after subscribed.\n */\n syncStatus$: SubjectWitness<TStatusIbGib>;\n syncStatusSubscriptions: SubscriptionWitness[];\n\n /**\n * For each communication saga, there will be one or more calls to each\n * space's `witness` function. This will produce arg & result ibgibs. This\n * is the observable stream/subject of those witness calls.\n */\n witnessFnArgsAndResults$: SubjectWitness<TSpaceOptionsIbGib | TSpaceResultIbGib>;\n\n syncIbGibs_All: IbGib_V1[];\n syncAddrs_All: IbGibAddr[];\n syncAddrs_All_AreTjps: IbGibAddr[];\n syncAddrs_All_WithTjps: IbGibAddr[];\n syncAddrs_All_WithoutTjps: IbGibAddr[];\n syncAddrs_Skipped: IbGibAddr[];\n syncAddrs_ToDo: IbGibAddr[];\n syncAddrs_InProgress: IbGibAddr[];\n syncAddrs_Failed: IbGibAddr[];\n}\n\n/**\n * Information about a sync operation over its entirety.\n *\n * ## notes\n *\n * This will be attached to each space arg/result ibgib, but this info object\n * WILL NOT be part of the internal `data` of either arg or result ibGib.\n */\nexport interface SyncSagaInfo\n extends SagaInfo<\n IbGib_V1,\n SyncSpaceOptionsData,\n SyncSpaceOptionsRel8ns,\n SyncSpaceOptionsIbGib,\n SyncSpaceResultData,\n SyncSpaceResultRel8ns,\n SyncSpaceResultIbGib,\n SyncStatusIbGib> {\n}\n\n// export interface SyncCycleInfo {\n// arg: SyncSpaceOptionsIbGib;\n// result?: SyncSpaceResultIbGib;\n// }\n\n/**\n * AWS-specific outerspace type\n */\nexport type AWSRegion = 'us-east-1' | string;\n\nexport interface StatusIbInfo {\n /**\n * Code for the given status.\n *\n */\n statusCode: StatusCode,\n spaceType: SpaceType,\n spaceSubtype: SpaceSubtype,\n sagaId: string,\n delimiter?: string,\n}\n", "import { HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { AlphabetIndexingMode, BlockModeOptions, SaltStrategy } from '@ibgib/encrypt-gib/dist/types.mjs';\nimport { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { IbGibAddr, } from '@ibgib/ts-gib/dist/types.mjs';\n\nimport { ENCRYPTION_REL8N_NAME } from './encrypt-constants.mjs';\n\n\n\nexport type EncryptionMethod = 'encrypt-gib';\n/**\n * Discriminator for the algorithm used in encryption that specifies the\n * algorithm used in encryption.\n *\n * The value of this will decide which descending encryption interface is used\n * that specifies parameters specific to this method.\n */\nexport const EncryptionMethod = {\n /**\n * custom probably very weak algorithm that uses indexing into a recursive\n * hash-based rounding function instead of keystream generation.\n */\n encrypt_gib: 'encrypt-gib' as EncryptionMethod,\n}\nexport const VALID_ENCRYPTION_METHODS = Object.values(EncryptionMethod);\n\n/**\n * Encryption-specific information that will form the {@link EncryptionData_V1}\n * shape. If you examine that interface, you'll see that it is this type\n */\nexport interface EncryptionInfo {\n name: string;\n description?: string;\n /**\n * @see {@link EncryptionMethod}\n */\n method: EncryptionMethod;\n}\n\n/**\n * Parameter information that is specific to the encrypt-gib algorithm.\n */\nexport interface EncryptionInfo_EncryptGib extends EncryptionInfo {\n method: 'encrypt-gib'\n /**\n * This is the algorithm that encrypt-gib will use in its\n * internal hashing round function to encrypt the data.\n */\n hashAlgorithm: HashAlgorithm;\n /**\n * This is an initial number of recursions to perform to \"get farther away\"\n * from the password. It is a one-time cost at the beginning of the\n * entire encryption process, so it does not cost more with more data.\n */\n initialRecursions: number;\n /**\n * This is the number of internal hashes per round function, which is per\n * hex character of data. So the more recursions here, the longer it is\n * going to take to encrypt/decrypt.\n */\n recursionsPerHash?: number;\n /**\n * Salt used throughout hashing in encryption/decryption. The longer and\n * more random, the better for security. But there is also a resource cost.\n */\n salt: string;\n /**\n * Stronger are the perHash options.\n *\n * 'prependPerHash' | 'appendPerHash' | 'initialPrepend' | 'initialAppend';\n */\n saltStrategy?: SaltStrategy;\n /**\n * The encrypted data is a delimited list of indices.\n *\n * @default \",\" (comma-delimited)\n */\n encryptedDataDelimiter?: string;\n /**\n * indexOf vs. lastIndexOf when recording the plaintext char's index into the jit alphabet.\n *\n * @see {@link AlphabetIndexingMode}\n */\n indexingMode?: AlphabetIndexingMode;\n /**\n * boolean determines if the algorithm is run in block mode (relatively\n * stronger but slower) or in stream mode (faster but weaker).\n * @see {@link BlockModeOptions}\n */\n blockMode: boolean;\n /**\n * @see {@link BlockModeOptions}\n */\n blockModeOptions?: BlockModeOptions;\n}\n\n/**\n * @see {@link EncryptionIbGib_V1}\n */\nexport type EncryptionData_V1 = IbGibData_V1 & EncryptionInfo & (\n EncryptionInfo_EncryptGib // extends this with logical OR of subtypes\n);\n\n/**\n * @see {@link EncryptionIbGib_V1}\n */\nexport interface EncryptionRel8ns_V1 extends IbGibRel8ns_V1 { }\n\n/**\n * IbGib that represents encryption settings.\n *\n * This determines the {@link EncryptionMethod}\n */\nexport interface EncryptionIbGib_V1 extends IbGib_V1<EncryptionData_V1, EncryptionRel8ns_V1> { }\n\n/**\n * Data for the actual encrypted ciphertext.\n */\nexport interface CiphertextData<TMetadata = any> extends IbGibData_V1 {\n ciphertext?: string;\n metadata?: TMetadata;\n}\n\n/**\n * Rel8ns for the actual encrypted ciphertext\n */\nexport interface CiphertextRel8ns extends IbGibRel8ns_V1 {\n // [ENCRYPTION_REL8N_NAME]?: IbGibAddr[];\n}\n\n/**\n * Ibgib for the actual encrypted content, as opposed to the\n * encryption secret (password) or encryption method/algorithm.\n */\nexport interface CiphertextIbGib_V1<TMetadata = any>\n extends IbGib_V1<CiphertextData<TMetadata>, CiphertextRel8ns> {\n}\n", "import { HELPER_LOG_A_LOT } from \"../constants.mjs\";\n\nconst logalot = HELPER_LOG_A_LOT || true;\n\nexport declare class SsmlTypes {\n /**\n * Describes how the text should be interpreted. This lets you\n * provide additional context to the text and eliminate any\n * ambiguity on how Alexa should render the text. Indicate how\n * Alexa should interpret the text with the interpret-as attribute.\n *\n * Note that the Alexa service attempts to interpret the provided\n * text correctly based on the text\u2019s formatting even without this\n * tag. For example, if your output speech includes \u201C202-555-1212\u201D,\n * Alexa speaks each individual digit, with a brief pause for each\n * dash. You don\u2019t need to use <say-as interpret-as=\"telephone\"> in\n * this case. However, if you provided the text \u201C2025551212\u201D, but\n * you wanted Alexa to speak it as a phone number, you would need\n * to use <say-as interpret-as=\"telephone\">.\n *\n * @example\n * <speak>\n * Here is a number spoken as a cardinal number:\n * <say-as interpret-as=\"cardinal\">12345</say-as>.\n * Here is the same number with each digit spoken separately:\n * <say-as interpret-as=\"digits\">12345</say-as>.\n * Here is a word spelled out: <say-as interpret-as=\"spell-out\">hello</say-as>\n * </speak>\n *\n * @see\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#say-as\n */\n static sayAs({ text, interpret, format }: {\n /**\n * Text to specify interpretation.\n */\n text: string;\n /**\n * Value that indicates how text should be interpreted.\n *\n * @see {InterpretAs}\n */\n interpret: InterpretAs;\n /**\n * Only used when interpret-as is set to date. Set to one of\n * the following to indicate format of the date:\n *\n * mdy\n * dmy\n * ymd\n * md\n * dm\n * ym\n * my\n * d\n * m\n * y\n *\n * Alternatively, if you provide the date in YYYYMMDD format,\n * the format attribute is ignored. You can include question\n * marks (?) for portions of the date to leave out. For\n * instance, Alexa would speak <say-as interpret-as=\"date\">????\n * 0922</say-as> as \u201CSeptember 22nd\u201D.\n */\n format?: SayAsDate;\n }): string;\n}\n\nexport type InterpretAs = \"characters\" | \"spell-out\" | \"cardinal\" | \"number\" | \"ordinal\" | \"digits\" | \"fraction\" | \"unit\" | \"date\" | \"time\" | \"telephone\" | \"address\" | \"interjection\" | \"expletive\";\n/**\n * Values that indicate how Alexa should speak text.\n * To be used with Ssml.sayAs({text, interpret: As.characters})\n */\nexport const As = {\n /**\n * Spell out each letter.\n */\n characters: \"characters\",\n /**\n * Spell out each letter.\n */\n spell_out: \"spell-out\" as InterpretAs,\n /**\n * Interpret the value as a cardinal number.\n *\n * @example \"12\" is pronounced as \"twelve\" and not \"1-2\".\n */\n cardinal: \"cardinal\" as InterpretAs,\n /**\n * Interpret the value as a cardinal number.\n *\n * @example \"12\" is pronounced as \"twelve\" and not \"1-2\".\n */\n number: \"number\" as InterpretAs,\n /**\n * Interpret the value as an ordinal number.\n *\n * @example \"12\" is pronounced as \"twelfth\"\n */\n ordinal: \"ordinal\" as InterpretAs,\n /**\n * Spell each digit separately.\n */\n digits: \"digits\" as InterpretAs,\n /**\n * Interpret the value as a fraction. This works for both common\n * fractions (such as 3/20) and mixed fractions (such as 1+1/2).\n */\n fraction: \"fraction\" as InterpretAs,\n /**\n * Interpret a value as a measurement. The value should be either a\n * number or fraction followed by a unit (with no space in between)\n * or just a unit.\n */\n unit: \"unit\" as InterpretAs,\n /**\n * Interpret the value as a date. Specify the format with the\n * format attribute.\n */\n date: \"date\" as InterpretAs,\n /**\n * Interpret a value such as 1'21\" as duration in minutes and\n * seconds.\n */\n time: \"time\" as InterpretAs,\n /**\n * Interpret a value as a 7-digit or 10-digit telephone number.\n * This can also handle extensions (for example, 2025551212x345).\n */\n telephone: \"telephone\" as InterpretAs,\n /**\n * Interpret a value as part of street address.\n */\n address: \"address\" as InterpretAs,\n /**\n * askGib NOTE: SpeechCons are already implemented directly: e.g. `Ssml.speech(Con.abracadabra)`\n *\n * Interpret the value as an interjection. Alexa speaks the text in\n * a more expressive voice. For optimal results, only use the\n * supported interjections and surround each one with a pause. For\n *\n * @example\n * <say-as interpret-as=\"interjection\">Wow.</say-as>.\n *\n * Speechcons are supported for English (US), English (UK), and\n * German.\n */\n interjection: \"interjection\" as InterpretAs,\n /**\n * \u201CBleep\u201D out the content inside the tag.\n */\n expletive: \"expletive\" as InterpretAs,\n};\nexport type SayAsDate = \"mdy\" | \"dmy\" | \"ymd\" | \"md\" | \"dm\" | \"ym\" | \"my\" | \"d\" | \"m\" | \"y\";\n/**\n * Date formats, used with @see {sayAs} function when\n * @see {InterpretAs} is \"date\".\n *\n * Alternatively, if you provide the date in YYYYMMDD format, the\n * format attribute is ignored. You can include question marks (?) for\n * portions of the date to leave out. For instance, Alexa would speak\n * <say-as interpret-as=\"date\">????0922</say-as> as \u201CSeptember 22nd\u201D.\n */\nexport const SayAsDate = {\n mdy: \"mdy\" as SayAsDate,\n dmy: \"dmy\" as SayAsDate,\n ymd: \"ymd\" as SayAsDate,\n md: \"md\" as SayAsDate,\n dm: \"dm\" as SayAsDate,\n ym: \"ym\" as SayAsDate,\n my: \"my\" as SayAsDate,\n d: \"d\" as SayAsDate,\n m: \"m\" as SayAsDate,\n y: \"y\" as SayAsDate,\n};\nexport type ProsodyRateType = \"x-slow\" | \"slow\" | \"medium\" | \"fast\" | \"x-fast\" | number;\nexport type ProsodyPitchType = \"x-low\" | \"low\" | \"medium\" | \"high\" | \"x-high\" | number;\nexport type ProsodyVolumeType = \"silent\" | \"x-soft\" | \"soft\" | \"medium\" | \"loud\" | \"x-loud\" | number;\nexport type SpeechCon =\n \"abracadabra\" | \"achoo\" | \"aha\" | \"ahem\" | \"ahoy\" | \"all righty\" | \"aloha\" | \"aooga\" | \"argh\" | \"arrivederci\" | \"as you wish\" | \"attagirl\" | \"au revoir\" | \"avast ye\" | \"aw man\" | \"baa\" | \"bada bing bada boom\" | \"bah humbug\" | \"bam\" | \"bang\" | \"batter up\" | \"bazinga\" | \"beep beep\" | \"bingo\" | \"blah\" | \"blarg\" | \"blast\" | \"boing\" | \"bon appetit\" | \"bonjour\" | \"bon voyage\" | \"boo\" | \"boo hoo\" | \"boom\" | \"booya\" | \"bravo\" | \"bummer\" | \"caw\" | \"cha ching\" | \"checkmate\" | \"cheerio\" | \"cheers\" | \"cheer up\" | \"chirp\" | \"choo choo\" | \"clank\" | \"click clack\" | \"cock a doodle doo\" | \"coo\" | \"cowabunga\" | \"darn\" | \"ding dong\" | \"ditto\" | \"d\u2019oh\" | \"dot dot dot\" | \"duh\" | \"dum\" | \"dun dun dun\" | \"dynomite\" | \"eek\" | \"eep\" | \"encore\" | \"en gard\" | \"eureka\" | \"fancy that\" | \"geronimo\" | \"giddy up\" | \"good grief\" | \"good luck\" | \"good riddance\" | \"gotcha\" | \"great scott\" | \"heads up\" | \"hear hear\" | \"hip hip hooray\" | \"hiss\" | \"honk\" | \"howdy\" | \"hurrah\" | \"hurray\" | \"huzzah\" | \"jeepers creepers\" | \"jiminy cricket\" | \"jinx\" | \"just kidding\" | \"kaboom\" | \"kablam\" | \"kaching\" | \"kapow\" | \"katchow\" | \"kazaam\" | \"kerbam\" | \"kerboom\" | \"kerching\" | \"kerchoo\" | \"kerflop\" | \"kerplop\" | \"kerplunk\" | \"kerpow\" | \"kersplat\" | \"kerthump\" | \"knock knock\" | \"le sigh\" | \"look out\" | \"mamma mia\" | \"man overboard\" | \"mazel tov\" | \"meow\" | \"merci\" | \"moo\" | \"nanu nanu\" | \"neener neener\" | \"no way\" | \"now now\" | \"oh boy\" | \"oh brother\" | \"oh dear\" | \"oh my\" | \"oh snap\" | \"oink\" | \"okey dokey\" | \"oof\" | \"ooh la la\" | \"open sesame\" | \"ouch\" | \"oy\" | \"phew\" | \"phooey\" | \"ping\" | \"plop\" | \"poof\" | \"pop\" | \"pow\" | \"quack\" | \"read \u2018em and weep\" | \"ribbit\" | \"righto\" | \"roger\" | \"ruh roh\" | \"shucks\" | \"splash\" | \"spoiler alert\" | \"squee\" | \"swish\" | \"swoosh\" | \"ta da\" | \"ta ta\" | \"tee hee\" | \"there there\" | \"thump\" | \"tick tick tick\" | \"tick-tock\" | \"touche\" | \"tsk tsk\" | \"tweet\" | \"uh huh\" | \"uh oh\" | \"um\" | \"voila\" | \"vroom\" | \"wahoo\" | \"wah wah\" | \"watch out\" | \"way to go\" | \"well done\" | \"well well\" | \"wham\" | \"whammo\" | \"whee\" | \"whew\" | \"woof\" | \"whoops a daisy\" | \"whoosh\" | \"woo hoo\" | \"wow\" | \"wowza\" | \"wowzer\" | \"yadda yadda yadda\" | \"yay\" | \"yikes\" | \"yippee\" | \"yoink\" | \"yoo hoo\" | \"you bet\" | \"yowza\" | \"yowzer\" | \"yuck\" | \"yum\" | \"zap\" | \"zing\" | \"zoinks\";\n/**\n * Special interjections that Alexa can say.\n * I have this called only \"Con\" for readability of calling code.\n *\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speechcon-reference\n *\n * All spaces in keys are replaced with underscores.\n */\nexport const Con = {\n abracadabra: \"abracadabra\" as SpeechCon,\n achoo: \"achoo\" as SpeechCon,\n aha: \"aha\" as SpeechCon,\n ahem: \"ahem\" as SpeechCon,\n ahoy: \"ahoy\" as SpeechCon,\n all_righty: \"all righty\" as SpeechCon,\n aloha: \"aloha\" as SpeechCon,\n aooga: \"aooga\" as SpeechCon,\n argh: \"argh\" as SpeechCon,\n arrivederci: \"arrivederci\" as SpeechCon,\n as_you_wish: \"as you wish\" as SpeechCon,\n attagirl: \"attagirl\" as SpeechCon,\n au_revoir: \"au revoir\" as SpeechCon,\n avast_ye: \"avast ye\" as SpeechCon,\n aw_man: \"aw man\" as SpeechCon,\n baa: \"baa\" as SpeechCon,\n bada_bing_bada_boom: \"bada bing bada boom\" as SpeechCon,\n bah_humbug: \"bah humbug\" as SpeechCon,\n bam: \"bam\" as SpeechCon,\n bang: \"bang\" as SpeechCon,\n batter_up: \"batter up\" as SpeechCon,\n bazinga: \"bazinga\" as SpeechCon,\n beep_beep: \"beep beep\" as SpeechCon,\n bingo: \"bingo\" as SpeechCon,\n blah: \"blah\" as SpeechCon,\n blarg: \"blarg\" as SpeechCon,\n blast: \"blast\" as SpeechCon,\n boing: \"boing\" as SpeechCon,\n bon_appetit: \"bon appetit\" as SpeechCon,\n bonjour: \"bonjour\" as SpeechCon,\n bon_voyage: \"bon voyage\" as SpeechCon,\n boo: \"boo\" as SpeechCon,\n boo_hoo: \"boo hoo\" as SpeechCon,\n boom: \"boom\" as SpeechCon,\n booya: \"booya\" as SpeechCon,\n bravo: \"bravo\" as SpeechCon,\n bummer: \"bummer\" as SpeechCon,\n caw: \"caw\" as SpeechCon,\n cha_ching: \"cha ching\" as SpeechCon,\n checkmate: \"checkmate\" as SpeechCon,\n cheerio: \"cheerio\" as SpeechCon,\n cheers: \"cheers\" as SpeechCon,\n cheer_up: \"cheer up\" as SpeechCon,\n chirp: \"chirp\" as SpeechCon,\n choo_choo: \"choo choo\" as SpeechCon,\n clank: \"clank\" as SpeechCon,\n click_clack: \"click clack\" as SpeechCon,\n cock_a_doodle_doo: \"cock a doodle doo\" as SpeechCon,\n coo: \"coo\" as SpeechCon,\n cowabunga: \"cowabunga\" as SpeechCon,\n darn: \"darn\" as SpeechCon,\n ding_dong: \"ding dong\" as SpeechCon,\n ditto: \"ditto\" as SpeechCon,\n doh: \"doh\" as SpeechCon,\n dot_dot_dot: \"dot dot dot\" as SpeechCon,\n duh: \"duh\" as SpeechCon,\n dum: \"dum\" as SpeechCon,\n dun_dun_dun: \"dun dun dun\" as SpeechCon,\n dynomite: \"dynomite\" as SpeechCon,\n eek: \"eek\" as SpeechCon,\n eep: \"eep\" as SpeechCon,\n encore: \"encore\" as SpeechCon,\n en_gard: \"en gard\" as SpeechCon,\n eureka: \"eureka\" as SpeechCon,\n fancy_that: \"fancy that\" as SpeechCon,\n geronimo: \"geronimo\" as SpeechCon,\n giddy_up: \"giddy up\" as SpeechCon,\n good_grief: \"good grief\" as SpeechCon,\n good_luck: \"good luck\" as SpeechCon,\n good_riddance: \"good riddance\" as SpeechCon,\n gotcha: \"gotcha\" as SpeechCon,\n great_scott: \"great scott\" as SpeechCon,\n heads_up: \"heads up\" as SpeechCon,\n hear_hear: \"hear hear\" as SpeechCon,\n hip_hip_hooray: \"hip hip hooray\" as SpeechCon,\n hiss: \"hiss\" as SpeechCon,\n honk: \"honk\" as SpeechCon,\n howdy: \"howdy\" as SpeechCon,\n hurrah: \"hurrah\" as SpeechCon,\n hurray: \"hurray\" as SpeechCon,\n huzzah: \"huzzah\" as SpeechCon,\n jeepers_creepers: \"jeepers creepers\" as SpeechCon,\n jiminy_cricket: \"jiminy cricket\" as SpeechCon,\n jinx: \"jinx\" as SpeechCon,\n just_kidding: \"just kidding\" as SpeechCon,\n kaboom: \"kaboom\" as SpeechCon,\n kablam: \"kablam\" as SpeechCon,\n kaching: \"kaching\" as SpeechCon,\n kapow: \"kapow\" as SpeechCon,\n katchow: \"katchow\" as SpeechCon,\n kazaam: \"kazaam\" as SpeechCon,\n kerbam: \"kerbam\" as SpeechCon,\n kerboom: \"kerboom\" as SpeechCon,\n kerching: \"kerching\" as SpeechCon,\n kerchoo: \"kerchoo\" as SpeechCon,\n kerflop: \"kerflop\" as SpeechCon,\n kerplop: \"kerplop\" as SpeechCon,\n kerplunk: \"kerplunk\" as SpeechCon,\n kerpow: \"kerpow\" as SpeechCon,\n kersplat: \"kersplat\" as SpeechCon,\n kerthump: \"kerthump\" as SpeechCon,\n knock_knock: \"knock knock\" as SpeechCon,\n le_sigh: \"le sigh\" as SpeechCon,\n look_out: \"look out\" as SpeechCon,\n mamma_mia: \"mamma mia\" as SpeechCon,\n man_overboard: \"man overboard\" as SpeechCon,\n mazel_tov: \"mazel tov\" as SpeechCon,\n meow: \"meow\" as SpeechCon,\n merci: \"merci\" as SpeechCon,\n moo: \"moo\" as SpeechCon,\n nanu_nanu: \"nanu nanu\" as SpeechCon,\n neener_neener: \"neener neener\" as SpeechCon,\n no_way: \"no way\" as SpeechCon,\n now_now: \"now now\" as SpeechCon,\n oh_boy: \"oh boy\" as SpeechCon,\n oh_brother: \"oh brother\" as SpeechCon,\n oh_dear: \"oh dear\" as SpeechCon,\n oh_my: \"oh my\" as SpeechCon,\n oh_snap: \"oh snap\" as SpeechCon,\n oink: \"oink\" as SpeechCon,\n okey_dokey: \"okey dokey\" as SpeechCon,\n oof: \"oof\" as SpeechCon,\n ooh_la_la: \"ooh la la\" as SpeechCon,\n open_sesame: \"open sesame\" as SpeechCon,\n ouch: \"ouch\" as SpeechCon,\n oy: \"oy\" as SpeechCon,\n phew: \"phew\" as SpeechCon,\n phooey: \"phooey\" as SpeechCon,\n ping: \"ping\" as SpeechCon,\n plop: \"plop\" as SpeechCon,\n poof: \"poof\" as SpeechCon,\n pop: \"pop\" as SpeechCon,\n pow: \"pow\" as SpeechCon,\n quack: \"quack\" as SpeechCon,\n read_em_and_weep: \"read em and weep\" as SpeechCon,\n ribbit: \"ribbit\" as SpeechCon,\n righto: \"righto\" as SpeechCon,\n roger: \"roger\" as SpeechCon,\n ruh_roh: \"ruh roh\" as SpeechCon,\n shucks: \"shucks\" as SpeechCon,\n splash: \"splash\" as SpeechCon,\n spoiler_alert: \"spoiler alert\" as SpeechCon,\n squee: \"squee\" as SpeechCon,\n swish: \"swish\" as SpeechCon,\n swoosh: \"swoosh\" as SpeechCon,\n ta_da: \"ta da\" as SpeechCon,\n ta_ta: \"ta ta\" as SpeechCon,\n tee_hee: \"tee hee\" as SpeechCon,\n there_there: \"there there\" as SpeechCon,\n thump: \"thump\" as SpeechCon,\n tick_tick_tick: \"tick tick tick\" as SpeechCon,\n tick_tock: \"tick tock\" as SpeechCon,\n touche: \"touche\" as SpeechCon,\n tsk_tsk: \"tsk tsk\" as SpeechCon,\n tweet: \"tweet\" as SpeechCon,\n uh_huh: \"uh huh\" as SpeechCon,\n uh_oh: \"uh oh\" as SpeechCon,\n um: \"um\" as SpeechCon,\n voila: \"voila\" as SpeechCon,\n vroom: \"vroom\" as SpeechCon,\n wahoo: \"wahoo\" as SpeechCon,\n wah_wah: \"wah wah\" as SpeechCon,\n watch_out: \"watch out\" as SpeechCon,\n way_to_go: \"way to go\" as SpeechCon,\n well_done: \"well done\" as SpeechCon,\n well_well: \"well well\" as SpeechCon,\n wham: \"wham\" as SpeechCon,\n whammo: \"whammo\" as SpeechCon,\n whee: \"whee\" as SpeechCon,\n whew: \"whew\" as SpeechCon,\n woof: \"woof\" as SpeechCon,\n whoops_a_daisy: \"whoops a daisy\" as SpeechCon,\n whoosh: \"whoosh\" as SpeechCon,\n woo_hoo: \"woo hoo\" as SpeechCon,\n wow: \"wow\" as SpeechCon,\n wowza: \"wowza\" as SpeechCon,\n wowzer: \"wowzer\" as SpeechCon,\n yadda_yadda_yadda: \"yadda yadda yadda\" as SpeechCon,\n yay: \"yay\" as SpeechCon,\n yikes: \"yikes\" as SpeechCon,\n yippee: \"yippee\" as SpeechCon,\n yoink: \"yoink\" as SpeechCon,\n yoo_hoo: \"yoo hoo\" as SpeechCon,\n you_bet: \"you bet\" as SpeechCon,\n yowza: \"yowza\" as SpeechCon,\n yowzer: \"yowzer\" as SpeechCon,\n yuck: \"yuck\" as SpeechCon,\n yum: \"yum\" as SpeechCon,\n zap: \"zap\" as SpeechCon,\n zing: \"zing\" as SpeechCon,\n zoinks: \"zoinks\" as SpeechCon,\n};\nexport type SpeechConUK = \"abracadabra\" | \"ace\" | \"achoo\" | \"ahoy\" | \"all\" | \"aloha\" | \"aooga\" | \"arrivederci\" | \"as if\" | \"as you wish\" | \"au revoir\" | \"aw\" | \"aw man\" | \"awesome\" | \"baa\" | \"bah humbug\" | \"bam\" | \"bang\" | \"bazinga\" | \"beep beep\" | \"bingo\" | \"blah\" | \"blarg\" | \"blast\" | \"blimey\" | \"bob's your uncle\" | \"boing\" | \"bon appetit\" | \"bon voyage\" | \"bonjour\" | \"boo\" | \"boo hoo\" | \"booya\" | \"bother\" | \"bravo\" | \"caw\" | \"cha ching\" | \"checkmate\" | \"cheer up\" | \"cheerio\" | \"cheers\" | \"chirp\" | \"choo choo\" | \"clank\" | \"clickety clack\" | \"cock a doodle doo\" | \"codswallop\" | \"coo\" | \"cowabunga\" | \"crikey\" | \"d'oh\" | \"darn\" | \"ditto\" | \"dot dot dot\" | \"duh\" | \"dun dun dun\" | \"eek\" | \"eep\" | \"en garde\" | \"encore\" | \"eureka\" | \"ew\" | \"fancy that\" | \"geronimo\" | \"giddy up\" | \"good golly\" | \"good grief\" | \"good luck\" | \"good riddance\" | \"gosh\" | \"gotcha\" | \"great scott\" | \"ha\" | \"ha ha\" | \"heads up\" | \"hear hear\" | \"hip hip hooray\" | \"hiss\" | \"honk\" | \"howdy\" | \"howzat\" | \"hurrah\" | \"hurray\" | \"huzzah\" | \"jeepers creepers\" | \"jiminy cricket\" | \"jinx\" | \"just kidding\" | \"kablam\" | \"kaboom\" | \"kaching\" | \"kapow\" | \"knock knock\" | \"le sigh\" | \"look out\" | \"mamma mia\" | \"man overboard\" | \"mazel tov\" | \"meow\" | \"merci\" | \"moo\" | \"no way\" | \"nom nom\" | \"now now\" | \"oh boy\" | \"oh dear\" | \"oh my\" | \"oh my giddy aunt\" | \"oh snap\" | \"okey dokey\" | \"oof\" | \"ooh la la\" | \"open sesame\" | \"ouch\" | \"ow\" | \"oy\" | \"pardon\" | \"phew\" | \"phooey\" | \"ping\" | \"plop\" | \"pop\" | \"pow\" | \"quack\" | \"read 'em and weep\" | \"ribbit\" | \"righto\" | \"roger\" | \"sigh\" | \"simples\" | \"splash\" | \"spoiler alert\" | \"squee\" | \"swish\" | \"swoosh\" | \"ta da\" | \"tallyho\" | \"tee hee\" | \"there there\" | \"thump\" | \"tick tick tick\" | \"tick tock\" | \"tosh\" | \"touche\" | \"tsk tsk\" | \"tut tut\" | \"tweet\" | \"uh huh\" | \"uh oh\" | \"voila\" | \"vroom\" | \"wahoo\" | \"watch out\" | \"way to go\" | \"well done\" | \"well well\" | \"wham\" | \"whammo\" | \"whee\" | \"whoop\" | \"whoops\" | \"whoops a daisy\" | \"whoosh\" | \"woo hoo\" | \"wow\" | \"wowza\" | \"yadda yadda yadda\" | \"yippee\" | \"yoink\" | \"you bet\" | \"yowza\" | \"yum\" | \"zap\" | \"zing\" | \"zoinks\";\nexport const ConUK = {\n abracadabra: \"abracadabra\" as SpeechConUK,\n ace: \"ace\" as SpeechConUK,\n achoo: \"achoo\" as SpeechConUK,\n ahoy: \"ahoy\" as SpeechConUK,\n all: \"all\" as SpeechConUK,\n aloha: \"aloha\" as SpeechConUK,\n aooga: \"aooga\" as SpeechConUK,\n arrivederci: \"arrivederci\" as SpeechConUK,\n as_if: \"as if\" as SpeechConUK,\n as_you_wish: \"as you wish\" as SpeechConUK,\n au_revoir: \"au revoir\" as SpeechConUK,\n aw: \"aw\" as SpeechConUK,\n aw_man: \"aw man\" as SpeechConUK,\n awesome: \"awesome\" as SpeechConUK,\n baa: \"baa\" as SpeechConUK,\n bah_humbug: \"bah humbug\" as SpeechConUK,\n bam: \"bam\" as SpeechConUK,\n bang: \"bang\" as SpeechConUK,\n bazinga: \"bazinga\" as SpeechConUK,\n beep_beep: \"beep beep\" as SpeechConUK,\n bingo: \"bingo\" as SpeechConUK,\n blah: \"blah\" as SpeechConUK,\n blarg: \"blarg\" as SpeechConUK,\n blast: \"blast\" as SpeechConUK,\n blimey: \"blimey\" as SpeechConUK,\n bobs_your_uncle: \"bobs your uncle\" as SpeechConUK,\n boing: \"boing\" as SpeechConUK,\n bon_appetit: \"bon appetit\" as SpeechConUK,\n bon_voyage: \"bon voyage\" as SpeechConUK,\n bonjour: \"bonjour\" as SpeechConUK,\n boo: \"boo\" as SpeechConUK,\n boo_hoo: \"boo hoo\" as SpeechConUK,\n booya: \"booya\" as SpeechConUK,\n bother: \"bother\" as SpeechConUK,\n bravo: \"bravo\" as SpeechConUK,\n caw: \"caw\" as SpeechConUK,\n cha_ching: \"cha ching\" as SpeechConUK,\n checkmate: \"checkmate\" as SpeechConUK,\n cheer_up: \"cheer up\" as SpeechConUK,\n cheerio: \"cheerio\" as SpeechConUK,\n cheers: \"cheers\" as SpeechConUK,\n chirp: \"chirp\" as SpeechConUK,\n choo_choo: \"choo choo\" as SpeechConUK,\n clank: \"clank\" as SpeechConUK,\n clickety_clack: \"clickety clack\" as SpeechConUK,\n cock_a_doodle_doo: \"cock a doodle doo\" as SpeechConUK,\n codswallop: \"codswallop\" as SpeechConUK,\n coo: \"coo\" as SpeechConUK,\n cowabunga: \"cowabunga\" as SpeechConUK,\n crikey: \"crikey\" as SpeechConUK,\n doh: \"doh\" as SpeechConUK,\n darn: \"darn\" as SpeechConUK,\n ditto: \"ditto\" as SpeechConUK,\n dot_dot_dot: \"dot dot dot\" as SpeechConUK,\n duh: \"duh\" as SpeechConUK,\n dun_dun_dun: \"dun dun dun\" as SpeechConUK,\n eek: \"eek\" as SpeechConUK,\n eep: \"eep\" as SpeechConUK,\n en_garde: \"en garde\" as SpeechConUK,\n encore: \"encore\" as SpeechConUK,\n eureka: \"eureka\" as SpeechConUK,\n ew: \"ew\" as SpeechConUK,\n fancy_that: \"fancy that\" as SpeechConUK,\n geronimo: \"geronimo\" as SpeechConUK,\n giddy_up: \"giddy up\" as SpeechConUK,\n good_golly: \"good golly\" as SpeechConUK,\n good_grief: \"good grief\" as SpeechConUK,\n good_luck: \"good luck\" as SpeechConUK,\n good_riddance: \"good riddance\" as SpeechConUK,\n gosh: \"gosh\" as SpeechConUK,\n gotcha: \"gotcha\" as SpeechConUK,\n great_scott: \"great scott\" as SpeechConUK,\n ha: \"ha\" as SpeechConUK,\n ha_ha: \"ha ha\" as SpeechConUK,\n heads_up: \"heads up\" as SpeechConUK,\n hear_hear: \"hear hear\" as SpeechConUK,\n hip_hip_hooray: \"hip hip hooray\" as SpeechConUK,\n hiss: \"hiss\" as SpeechConUK,\n honk: \"honk\" as SpeechConUK,\n howdy: \"howdy\" as SpeechConUK,\n howzat: \"howzat\" as SpeechConUK,\n hurrah: \"hurrah\" as SpeechConUK,\n hurray: \"hurray\" as SpeechConUK,\n huzzah: \"huzzah\" as SpeechConUK,\n jeepers_creepers: \"jeepers creepers\" as SpeechConUK,\n jiminy_cricket: \"jiminy cricket\" as SpeechConUK,\n jinx: \"jinx\" as SpeechConUK,\n just_kidding: \"just kidding\" as SpeechConUK,\n kablam: \"kablam\" as SpeechConUK,\n kaboom: \"kaboom\" as SpeechConUK,\n kaching: \"kaching\" as SpeechConUK,\n kapow: \"kapow\" as SpeechConUK,\n knock_knock: \"knock knock\" as SpeechConUK,\n le_sigh: \"le sigh\" as SpeechConUK,\n look_out: \"look out\" as SpeechConUK,\n mamma_mia: \"mamma mia\" as SpeechConUK,\n man_overboard: \"man overboard\" as SpeechConUK,\n mazel_tov: \"mazel tov\" as SpeechConUK,\n meow: \"meow\" as SpeechConUK,\n merci: \"merci\" as SpeechConUK,\n moo: \"moo\" as SpeechConUK,\n no_way: \"no way\" as SpeechConUK,\n nom_nom: \"nom nom\" as SpeechConUK,\n now_now: \"now now\" as SpeechConUK,\n oh_boy: \"oh boy\" as SpeechConUK,\n oh_dear: \"oh dear\" as SpeechConUK,\n oh_my: \"oh my\" as SpeechConUK,\n oh_my_giddy_aunt: \"oh my giddy aunt\" as SpeechConUK,\n oh_snap: \"oh snap\" as SpeechConUK,\n okey_dokey: \"okey dokey\" as SpeechConUK,\n oof: \"oof\" as SpeechConUK,\n ooh_la_la: \"ooh la la\" as SpeechConUK,\n open_sesame: \"open sesame\" as SpeechConUK,\n ouch: \"ouch\" as SpeechConUK,\n ow: \"ow\" as SpeechConUK,\n oy: \"oy\" as SpeechConUK,\n pardon: \"pardon\" as SpeechConUK,\n phew: \"phew\" as SpeechConUK,\n phooey: \"phooey\" as SpeechConUK,\n ping: \"ping\" as SpeechConUK,\n plop: \"plop\" as SpeechConUK,\n pop: \"pop\" as SpeechConUK,\n pow: \"pow\" as SpeechConUK,\n quack: \"quack\" as SpeechConUK,\n read_em_and_weep: \"read em and weep\" as SpeechConUK,\n ribbit: \"ribbit\" as SpeechConUK,\n righto: \"righto\" as SpeechConUK,\n roger: \"roger\" as SpeechConUK,\n sigh: \"sigh\" as SpeechConUK,\n simples: \"simples\" as SpeechConUK,\n splash: \"splash\" as SpeechConUK,\n spoiler_alert: \"spoiler alert\" as SpeechConUK,\n squee: \"squee\" as SpeechConUK,\n swish: \"swish\" as SpeechConUK,\n swoosh: \"swoosh\" as SpeechConUK,\n ta_da: \"ta da\" as SpeechConUK,\n tallyho: \"tallyho\" as SpeechConUK,\n tee_hee: \"tee hee\" as SpeechConUK,\n there_there: \"there there\" as SpeechConUK,\n thump: \"thump\" as SpeechConUK,\n tick_tick_tick: \"tick tick tick\" as SpeechConUK,\n tick_tock: \"tick tock\" as SpeechConUK,\n tosh: \"tosh\" as SpeechConUK,\n touche: \"touche\" as SpeechConUK,\n tsk_tsk: \"tsk tsk\" as SpeechConUK,\n tut_tut: \"tut tut\" as SpeechConUK,\n tweet: \"tweet\" as SpeechConUK,\n uh_huh: \"uh huh\" as SpeechConUK,\n uh_oh: \"uh oh\" as SpeechConUK,\n voila: \"voila\" as SpeechConUK,\n vroom: \"vroom\" as SpeechConUK,\n wahoo: \"wahoo\" as SpeechConUK,\n watch_out: \"watch out\" as SpeechConUK,\n way_to_go: \"way to go\" as SpeechConUK,\n well_done: \"well done\" as SpeechConUK,\n well_well: \"well well\" as SpeechConUK,\n wham: \"wham\" as SpeechConUK,\n whammo: \"whammo\" as SpeechConUK,\n whee: \"whee\" as SpeechConUK,\n whoop: \"whoop\" as SpeechConUK,\n whoops: \"whoops\" as SpeechConUK,\n whoops_a_daisy: \"whoops a daisy\" as SpeechConUK,\n whoosh: \"whoosh\" as SpeechConUK,\n woo_hoo: \"woo hoo\" as SpeechConUK,\n wow: \"wow\" as SpeechConUK,\n wowza: \"wowza\" as SpeechConUK,\n yadda_yadda_yadda: \"yadda yadda yadda\" as SpeechConUK,\n yippee: \"yippee\" as SpeechConUK,\n yoink: \"yoink\" as SpeechConUK,\n you_bet: \"you bet\" as SpeechConUK,\n yowza: \"yowza\" as SpeechConUK,\n yum: \"yum\" as SpeechConUK,\n zap: \"zap\" as SpeechConUK,\n zing: \"zing\" as SpeechConUK,\n zoinks: \"zoinks\" as SpeechConUK,\n};\nexport type SpeechConDE = \"aber hallo\" | \"aber sicher\" | \"abrakadabra\" | \"ach\" | \"ach du gr\u00FCne neune\" | \"ach du liebe zeit\" | \"ach du meine g\u00FCte\" | \"ach ja\" | \"ach so\" | \"achje\" | \"achtung\" | \"ade\" | \"ah\" | \"aha\" | \"\u00E4hm\" | \"ahoi\" | \"alles klar\" | \"aloha\" | \"als ob\" | \"argh\" | \"arrivederci\" | \"aso\" | \"au\" | \"au weia\" | \"aua\" | \"autsch\" | \"bazinga\" | \"bingo\" | \"bis bald\" | \"bis dann\" | \"bla\" | \"boing\" | \"bon appetit\" | \"bon voyage\" | \"bonjour\" | \"bravo\" | \"brumm\" | \"buh\" | \"buhu\" | \"bumm\" | \"bzz\" | \"da lachen ja die h\u00FChner\" | \"ding dong\" | \"dito\" | \"donner und doria\" | \"donnerwetter\" | \"ebenso\" | \"en garde\" | \"ey\" | \"geh nur\" | \"gemach\" | \"genug\" | \"gesundheit\" | \"gott im himmel\" | \"gr\u00FC\u00DF gott\" | \"gute reise\" | \"guten appetit\" | \"hach ja\" | \"halleluja\" | \"hals und beinbruch\" | \"halt\" | \"h\u00E4nde hoch\" | \"heiliger strohsack\" | \"heisa\" | \"hey\" | \"hihi\" | \"hipp hipp hurra\" | \"h\u00F6rt h\u00F6rt\" | \"h\u00FC\" | \"h\u00FCa\" | \"huch\" | \"huhu\" | \"hui\" | \"hurra\" | \"ich glaub ich bin im kino\" | \"ich glaub mein schwein pfeift\" | \"ich glaub mich knutscht ein elch\" | \"ich glaub mich laust der affe\" | \"ich glaub mich tritt ein pferd\" | \"igitt\" | \"iiieh\" | \"ist nicht dein ernst\" | \"japp\" | \"jawohl\" | \"jo\" | \"juhu\" | \"kein kommentar\" | \"keine ursache\" | \"kikeriki\" | \"klar\" | \"klick klack\" | \"kopf hoch\" | \"kuckuck\" | \"lass es dir schmecken\" | \"lecker\" | \"los\" | \"mach's gut\" | \"mahlzeit\" | \"mamma mia\" | \"mann \u00FCber bord\" | \"manometer\" | \"mazel tov\" | \"mein gott\" | \"merci\" | \"miau\" | \"mist\" | \"moin\" | \"muh\" | \"na klar\" | \"na sieh mal einer an\" | \"na und?\" | \"na?\" | \"naja\" | \"nanu?\" | \"ne\" | \"nee\" | \"nichts da\" | \"nix da\" | \"n\u00F6\" | \"null problemo\" | \"obacht\" | \"och\" | \"oh mann\" | \"oh mein gott\" | \"oh my god\" | \"oh nein\" | \"oh oh\" | \"ohne schei\u00DF\" | \"oink\" | \"oje\" | \"okey dokey\" | \"ooh la la\" | \"pfui\" | \"piep\" | \"plop\" | \"plumps\" | \"prima\" | \"prosit\" | \"prost\" | \"puff\" | \"puh\" | \"pustekuchen\" | \"schachmatt\" | \"schade\" | \"schau an\" | \"sesam \u00F6ffne dich\" | \"seufz\" | \"sieh an\" | \"siehe da\" | \"siehste?\" | \"spoileralarm\" | \"stimmt\" | \"super\" | \"supi\" | \"s\u00FC\u00DFes oder saures\" | \"tada\" | \"tats\u00E4chlich\" | \"tick tack\" | \"tja\" | \"touche\" | \"tsch\u00F6\" | \"t\u00FCrlich\" | \"tut\" | \"uff\" | \"verdammt\" | \"verflixt\" | \"viel gl\u00FCck\" | \"voila\" | \"von wegen\" | \"vorsicht\" | \"war nur ein scherz\" | \"was zur h\u00F6lle\" | \"weh mir\" | \"wehe\" | \"wie du meinst\" | \"willkommen\" | \"wow\" | \"wuff\" | \"yay\" | \"zugabe\" | \"zum wohl\";\nexport const ConDE = {\n aber_hallo: \"aber hallo\" as SpeechConDE,\n aber_sicher: \"aber sicher\" as SpeechConDE,\n abrakadabra: \"abrakadabra\" as SpeechConDE,\n ach: \"ach\" as SpeechConDE,\n ach_du_gr\u00FCne_neune: \"ach du gr\u00FCne neune\" as SpeechConDE,\n ach_du_liebe_zeit: \"ach du liebe zeit\" as SpeechConDE,\n ach_du_meine_g\u00FCte: \"ach du meine g\u00FCte\" as SpeechConDE,\n ach_ja: \"ach ja\" as SpeechConDE,\n ach_so: \"ach so\" as SpeechConDE,\n achje: \"achje\" as SpeechConDE,\n achtung: \"achtung\" as SpeechConDE,\n ade: \"ade\" as SpeechConDE,\n ah: \"ah\" as SpeechConDE,\n aha: \"aha\" as SpeechConDE,\n \u00E4hm: \"\u00E4hm\" as SpeechConDE,\n ahoi: \"ahoi\" as SpeechConDE,\n alles_klar: \"alles klar\" as SpeechConDE,\n aloha: \"aloha\" as SpeechConDE,\n als_ob: \"als ob\" as SpeechConDE,\n argh: \"argh\" as SpeechConDE,\n arrivederci: \"arrivederci\" as SpeechConDE,\n aso: \"aso\" as SpeechConDE,\n au: \"au\" as SpeechConDE,\n au_weia: \"au weia\" as SpeechConDE,\n aua: \"aua\" as SpeechConDE,\n autsch: \"autsch\" as SpeechConDE,\n bazinga: \"bazinga\" as SpeechConDE,\n bingo: \"bingo\" as SpeechConDE,\n bis_bald: \"bis bald\" as SpeechConDE,\n bis_dann: \"bis dann\" as SpeechConDE,\n bla: \"bla\" as SpeechConDE,\n boing: \"boing\" as SpeechConDE,\n bon_appetit: \"bon appetit\" as SpeechConDE,\n bon_voyage: \"bon voyage\" as SpeechConDE,\n bonjour: \"bonjour\" as SpeechConDE,\n bravo: \"bravo\" as SpeechConDE,\n brumm: \"brumm\" as SpeechConDE,\n buh: \"buh\" as SpeechConDE,\n buhu: \"buhu\" as SpeechConDE,\n bumm: \"bumm\" as SpeechConDE,\n bzz: \"bzz\" as SpeechConDE,\n da_lachen_ja_die_h\u00FChner: \"da lachen ja die h\u00FChner\" as SpeechConDE,\n ding_dong: \"ding dong\" as SpeechConDE,\n dito: \"dito\" as SpeechConDE,\n donner_und_doria: \"donner und doria\" as SpeechConDE,\n donnerwetter: \"donnerwetter\" as SpeechConDE,\n ebenso: \"ebenso\" as SpeechConDE,\n en_garde: \"en garde\" as SpeechConDE,\n ey: \"ey\" as SpeechConDE,\n geh_nur: \"geh nur\" as SpeechConDE,\n gemach: \"gemach\" as SpeechConDE,\n genug: \"genug\" as SpeechConDE,\n gesundheit: \"gesundheit\" as SpeechConDE,\n gott_im_himmel: \"gott im himmel\" as SpeechConDE,\n gr\u00FC\u00DF_gott: \"gr\u00FC\u00DF gott\" as SpeechConDE,\n gute_reise: \"gute reise\" as SpeechConDE,\n guten_appetit: \"guten appetit\" as SpeechConDE,\n hach_ja: \"hach ja\" as SpeechConDE,\n halleluja: \"halleluja\" as SpeechConDE,\n hals_und_beinbruch: \"hals und beinbruch\" as SpeechConDE,\n halt: \"halt\" as SpeechConDE,\n h\u00E4nde_hoch: \"h\u00E4nde hoch\" as SpeechConDE,\n heiliger_strohsack: \"heiliger strohsack\" as SpeechConDE,\n heisa: \"heisa\" as SpeechConDE,\n hey: \"hey\" as SpeechConDE,\n hihi: \"hihi\" as SpeechConDE,\n hipp_hipp_hurra: \"hipp hipp hurra\" as SpeechConDE,\n h\u00F6rt_h\u00F6rt: \"h\u00F6rt h\u00F6rt\" as SpeechConDE,\n h\u00FC: \"h\u00FC\" as SpeechConDE,\n h\u00FCa: \"h\u00FCa\" as SpeechConDE,\n huch: \"huch\" as SpeechConDE,\n huhu: \"huhu\" as SpeechConDE,\n hui: \"hui\" as SpeechConDE,\n hurra: \"hurra\" as SpeechConDE,\n ich_glaub_ich_bin_im_kino: \"ich glaub ich bin im kino\" as SpeechConDE,\n ich_glaub_mein_schwein_pfeift: \"ich glaub mein schwein pfeift\" as SpeechConDE,\n ich_glaub_mich_knutscht_ein_elch: \"ich glaub mich knutscht ein elch\" as SpeechConDE,\n ich_glaub_mich_laust_der_affe: \"ich glaub mich laust der affe\" as SpeechConDE,\n ich_glaub_mich_tritt_ein_pferd: \"ich glaub mich tritt ein pferd\" as SpeechConDE,\n igitt: \"igitt\" as SpeechConDE,\n iiieh: \"iiieh\" as SpeechConDE,\n ist_nicht_dein_ernst: \"ist nicht dein ernst\" as SpeechConDE,\n japp: \"japp\" as SpeechConDE,\n jawohl: \"jawohl\" as SpeechConDE,\n jo: \"jo\" as SpeechConDE,\n juhu: \"juhu\" as SpeechConDE,\n kein_kommentar: \"kein kommentar\" as SpeechConDE,\n keine_ursache: \"keine ursache\" as SpeechConDE,\n kikeriki: \"kikeriki\" as SpeechConDE,\n klar: \"klar\" as SpeechConDE,\n klick_klack: \"klick klack\" as SpeechConDE,\n kopf_hoch: \"kopf hoch\" as SpeechConDE,\n kuckuck: \"kuckuck\" as SpeechConDE,\n lass_es_dir_schmecken: \"lass es dir schmecken\" as SpeechConDE,\n lecker: \"lecker\" as SpeechConDE,\n los: \"los\" as SpeechConDE,\n mach: \"mach's gut\" as SpeechConDE,\n mahlzeit: \"mahlzeit\" as SpeechConDE,\n mamma_mia: \"mamma mia\" as SpeechConDE,\n mann_\u00FCber_bord: \"mann \u00FCber bord\" as SpeechConDE,\n manometer: \"manometer\" as SpeechConDE,\n mazel_tov: \"mazel tov\" as SpeechConDE,\n mein_gott: \"mein gott\" as SpeechConDE,\n merci: \"merci\" as SpeechConDE,\n miau: \"miau\" as SpeechConDE,\n mist: \"mist\" as SpeechConDE,\n moin: \"moin\" as SpeechConDE,\n muh: \"muh\" as SpeechConDE,\n na_klar: \"na klar\" as SpeechConDE,\n na_sieh_mal_einer_an: \"na sieh mal einer an\" as SpeechConDE,\n na_und_: \"na und?\" as SpeechConDE,\n na_: \"na?\" as SpeechConDE,\n naja: \"naja\" as SpeechConDE,\n nanu: \"nanu\" as SpeechConDE,\n ne: \"ne\" as SpeechConDE,\n nee: \"nee\" as SpeechConDE,\n nichts_da: \"nichts da\" as SpeechConDE,\n nix_da: \"nix da\" as SpeechConDE,\n n\u00F6: \"n\u00F6\" as SpeechConDE,\n null_problemo: \"null problemo\" as SpeechConDE,\n obacht: \"obacht\" as SpeechConDE,\n och: \"och\" as SpeechConDE,\n oh_mann: \"oh mann\" as SpeechConDE,\n oh_mein_gott: \"oh mein gott\" as SpeechConDE,\n oh_my_god: \"oh my god\" as SpeechConDE,\n oh_nein: \"oh nein\" as SpeechConDE,\n oh_oh: \"oh oh\" as SpeechConDE,\n ohne_schei\u00DF: \"ohne schei\u00DF\" as SpeechConDE,\n oink: \"oink\" as SpeechConDE,\n oje: \"oje\" as SpeechConDE,\n okey_dokey: \"okey dokey\" as SpeechConDE,\n ooh_la_la: \"ooh la la\" as SpeechConDE,\n pfui: \"pfui\" as SpeechConDE,\n piep: \"piep\" as SpeechConDE,\n plop: \"plop\" as SpeechConDE,\n plumps: \"plumps\" as SpeechConDE,\n prima: \"prima\" as SpeechConDE,\n prosit: \"prosit\" as SpeechConDE,\n prost: \"prost\" as SpeechConDE,\n puff: \"puff\" as SpeechConDE,\n puh: \"puh\" as SpeechConDE,\n pustekuchen: \"pustekuchen\" as SpeechConDE,\n schachmatt: \"schachmatt\" as SpeechConDE,\n schade: \"schade\" as SpeechConDE,\n schau_an: \"schau an\" as SpeechConDE,\n sesam_\u00F6ffne_dich: \"sesam \u00F6ffne dich\" as SpeechConDE,\n seufz: \"seufz\" as SpeechConDE,\n sieh_an: \"sieh an\" as SpeechConDE,\n siehe_da: \"siehe da\" as SpeechConDE,\n siehste: \"siehste\" as SpeechConDE,\n spoileralarm: \"spoileralarm\" as SpeechConDE,\n stimmt: \"stimmt\" as SpeechConDE,\n super: \"super\" as SpeechConDE,\n supi: \"supi\" as SpeechConDE,\n s\u00FC\u00DFes_oder_saures: \"s\u00FC\u00DFes oder saures\" as SpeechConDE,\n tada: \"tada\" as SpeechConDE,\n tats\u00E4chlich: \"tats\u00E4chlich\" as SpeechConDE,\n tick_tack: \"tick tack\" as SpeechConDE,\n tja: \"tja\" as SpeechConDE,\n touche: \"touche\" as SpeechConDE,\n tsch\u00F6: \"tsch\u00F6\" as SpeechConDE,\n t\u00FCrlich: \"t\u00FCrlich\" as SpeechConDE,\n tut: \"tut\" as SpeechConDE,\n uff: \"uff\" as SpeechConDE,\n verdammt: \"verdammt\" as SpeechConDE,\n verflixt: \"verflixt\" as SpeechConDE,\n viel_gl\u00FCck: \"viel gl\u00FCck\" as SpeechConDE,\n voila: \"voila\" as SpeechConDE,\n von_wegen: \"von wegen\" as SpeechConDE,\n vorsicht: \"vorsicht\" as SpeechConDE,\n war_nur_ein_scherz: \"war nur ein scherz\" as SpeechConDE,\n was_zur_h\u00F6lle: \"was zur h\u00F6lle\" as SpeechConDE,\n weh_mir: \"weh mir\" as SpeechConDE,\n wehe: \"wehe\" as SpeechConDE,\n wie_du_meinst: \"wie du meinst\" as SpeechConDE,\n willkommen: \"willkommen\" as SpeechConDE,\n wow: \"wow\" as SpeechConDE,\n wuff: \"wuff\" as SpeechConDE,\n yay: \"yay\" as SpeechConDE,\n zugabe: \"zugabe\" as SpeechConDE,\n zum_wohl: \"zum wohl\" as SpeechConDE,\n};\nexport type Effect = \"whispered\";\nexport const Effect = {\n whispered: \"whispered\" as Effect,\n};\nexport type BreakStrengthType = \"none\" | \"x-weak\" | \"weak\" | \"medium\" | \"strong\" | \"x-strong\";\n/**\n * amazon:VB: Interpret the word as a verb (present simple).\n *\n * amazon:VBD: Interpret the word as a past participle.\n *\n * amazon:NN: Interpret the word as a noun.\n *\n * amazon:SENSE_1:\u2009 Use the non-default sense of the word. For example,\n * the noun \u201Cbass\u201D is pronounced differently depending on meaning.\n * The \u201Cdefault\u201D meaning is the lowest part of the musical range. The\n * alternate sense (which is still a noun) is a freshwater fish.\n * Specifying <speak><w role=\"amazon:SENSE_1\">bass</w>\"</speak>\n * renders the non-default pronunciation (freshwater fish).\n */\nexport type PartOfSpeech = \"amazon:VB\" | \"amazon:VBD\" | \"amazon:NN\" | \"amazon:SENSE_1\";\nexport const PartOfSpeech = {\n /**\n * Interpret the word as a verb (present simple).\n */\n verb: \"amazon:VB\" as PartOfSpeech,\n /**\n * Interpret the word as a past participle.\n */\n past_participle: \"amazon:VBD\" as PartOfSpeech,\n /**\n * Interpret the word as a noun.\n */\n noun: \"amazon:NN\" as PartOfSpeech,\n /**\n * Use the non-default sense of the word. For example,\n * the noun \u201Cbass\u201D is pronounced differently depending on meaning.\n * The \u201Cdefault\u201D meaning is the lowest part of the musical range.\n * The alternate sense (which is still a noun) is a freshwater\n * fish. Specifying\n * <speak><w role=\"amazon:SENSE_1\">bass</w>\"</speak>\n * renders the non-default pronunciation (freshwater fish).\n */\n sense1: \"amazon:SENSE_1\" as PartOfSpeech,\n};\n\nexport class Ssml {\n private static lc: string = `[${Ssml.name}]`;\n /**\n * Wraps a given list of paragraph strings in `<speak>` tags, with\n * optional paragraph `<p>` tags.\n *\n * @param paras individual paragraphs to be wrapped in <p></p> tags.\n * @param addParaTags If true, wraps individual strings in paras with `<p>` tags. Otherwise just concats.\n */\n static wrapSsmlSpeak(paras: string[], addParaTags: boolean = true): string {\n let result: string = \"<speak>\" +\n paras.reduce((agg, p) => {\n return addParaTags ? agg + \"<p>\" + p + \"</p>\" : agg + p;\n }, \"\") +\n \"</speak>\";\n return result;\n }\n /**\n * This simply replaces <speak> and </speak> tags with an empty\n * string.\n *\n * Use this when you want to add some text to existing ssml and\n * then re-wrap the ssml.\n *\n * @see {Helper.stripSsml} function.\n *\n * @param ssml with <speak> tag around the whole thing.\n */\n static unwrapSsmlSpeak(ssml: string): string {\n return ssml.replace(/\\<speak\\>/g, \"\").replace(/\\<\\/speak\\>/g, \"\");\n }\n /**\n * Simply wraps with <p> tag.\n *\n * Represents a paragraph. This tag provides extra-strong breaks\n * before and after the tag. This is equivalent to specifying a\n * pause with <break strength=\"x-strong\"/>.\n *\n * @param text to wrap\n */\n static p(text: string): string {\n return '<p>' + text + '</p>';\n }\n /**\n * Simply wraps with <s> tag.\n *\n * Represents a sentence. This tag provides strong breaks before\n * and after the tag.\n *\n * This is equivalent to:\n * Ending a sentence with a period (.).\n * Specifying a pause with <break strength=\"strong\"/>.\n\n * @param text to wrap\n */\n static s(text: string): string {\n return '<s>' + text + '</s>';\n }\n /**\n * Strips all tags within ssml to produce plain text.\n *\n * @see {Helper.unwrapSsmlSpeak} function.\n *\n * @param ssml to strip\n */\n static stripSsml(ssml: string): string {\n const stripped = ssml\n // Combines </p> <p> to not double para breaks\n .replace(/\\<\\/p\\>[ ]*\\<p\\>/g, \"<p>\")\n // remove spaces after <p>,</p> tags\n .replace(/\\<p\\>(?=[ ])/g, \"<p>\")\n .replace(/\\<\\/p\\>(?=[ ])/g, \"</p>\")\n // convert <p> and </p> to two new lines\n .replace(/\\<[\\/]*p\\>/g, \"\\n\\n\")\n // Strip all remaining tags\n .replace(/(<([^>]*)>)/ig, \"\")\n // Replace multiple spaces with a single space\n .replace(/ +/g, ' ')\n .replace(/\\\\n\\\\n\\\\n/g, \"\\n\\n\")\n // .replace(/^\\\\n+/, \"\")\n .replace(/^\\n+/, \"\")\n .replace(/\\n+$/, \"\");\n return stripped;\n }\n /**\n * Wraps a given text in an ssml phoneme tag with the given\n * pronunciation and alphabet.\n *\n * @param text Literal text that we're wrapping the phoneme tag around, e.g. \"sewing\".\n * @param pronunciation the phoneme itself, e.g. \"so\u028A\u026A\u014B\"\n * @param alphabet phoneme alphabet, either \"ipa\" or \"x-sampe\" (ATOW)\n *\n * @see {@link https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#prosody|SsmlReference}\n */\n static phoneme(text: string, pronunciation: string, alphabet: \"ipa\" | \"x-sampa\" = \"ipa\"): string {\n return `<phoneme alphabet=\"${alphabet}\" ph=\"${pronunciation}\">${text}</phoneme>`;\n }\n /**\n * Wraps a given text in an ssml emphasis tag.\n *\n * e.g. <emphasis level=\"${level}\">${text}</emphasis>`\n *\n * @param text to wrap with the emphasis tag\n * @param level attribute in emphasis tag. Valid values \"strong\" | \"moderate\" | \"reduced\" = \"moderate\"\n *\n * @see {@link https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#prosody|SsmlReference}\n */\n static emphasis(text: string, level: \"strong\" | \"moderate\" | \"reduced\" = \"moderate\"): string {\n return `<emphasis level=\"${level}\">${text}</emphasis>`;\n }\n /**\n * Wraps a given text in an ssml prosody tag with the given\n * options of rate, pitch, and/or volume.\n *\n * @param rate valid values ATOW \"x-slow\" | \"slow\" | \"medium\" | \"fast\" | \"x-fast\" | number,\n * @param pitch valid values ATOW \"x-low\" | \"low\" | \"medium\" | \"high\" | \"x-high\" | number,\n * @param volume valid values ATOW \"silent\" | \"x-soft\" | \"soft\" | \"medium\" | \"loud\" | \"x-loud\" | number\n *\n * @see {@link https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#prosody|SsmlReference}\n */\n // static prosody(text, { rate, pitch, volume }) {\n static prosody(text: string, { rate, pitch, volume }: {\n rate?: ProsodyRateType;\n pitch?: ProsodyPitchType;\n volume?: ProsodyVolumeType;\n }): string {\n const lc = `${Ssml.lc}${Ssml.prosody.name}`;\n let attrs = \"\";\n // adds the + to positive numbers\n if (rate || rate === 0) {\n const rateText = typeof rate === 'number' ?\n rate + \"%\" :\n rate;\n attrs += `rate=\"${rateText}\"`;\n }\n if (pitch || pitch === 0) {\n let pitchText: string;\n if (typeof pitch === 'number') {\n const pitchNum = pitch;\n if (pitch >= 0) {\n const max = 50;\n if (pitchNum > max) { console.warn(`${lc} max: ${max}, actual: ${pitchNum} (W: 7fd9706e59f24dba896e2de149904677)`); }\n pitchText = \"+\" + pitchNum + \"%\";\n } else {\n const min = -33.3;\n if (pitchNum < min) { console.warn(`${lc} min: ${min}, actual: ${pitchNum} (W: 90f4c21672034c51a8a95dcfcd281f98)`); }\n pitchText = \"-\" + pitchNum + \"%\";\n }\n } else {\n pitchText = pitch;\n }\n attrs = attrs ? attrs + \" \" : attrs;\n attrs += `pitch=\"${pitchText}\"`;\n }\n if (volume || volume === 0) {\n let volumeText: string;\n if (typeof volume === 'number') {\n let volumeNum = volume;\n if (volumeNum >= 0) {\n const max = 4.08;\n if (volumeNum > max) { console.warn(`${lc} max: ${max}, actual: ${volumeNum} (W: 7db9521e6b3e418faca89d2f5cfa4f2c)`); }\n volumeText = \"+\" + volumeNum + \"%\";\n } else {\n const min = -12;\n if (volumeNum < min) { console.warn(`${lc} min: ${min}, actual: ${volumeNum} (W: 49210d930272498e828d2c9a815ceea0)`); }\n }\n\n volumeText = volumeNum + \"%\";\n } else {\n volumeText = volume;\n\n }\n attrs = attrs ? attrs + \" \" : attrs;\n attrs += (volume ? `volume=\"${volumeText}\"` : \"\");\n }\n return \"<prosody \" + attrs + \">\" + text + \"</prosody>\";\n }\n /**\n * Generates SpeechCon SSML.\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speechcon-reference\n */\n static speech(speechCon: SpeechCon): string {\n return `<say-as interpret-as=\"interjection\">${speechCon}</say-as>`;\n }\n /**\n * Applies Amazon-specific effects to the speech.\n *\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#amazon-effect\n *\n * The name of the effect to apply to the speech. Available effects:\n * whispered: Applies a whispering effect to the speech.\n * @param effect Which amazon:effect. ATOW only whispered implemented.\n * @param s text to wrap in the effect.\n */\n static amazon(effect: Effect, s: string): string {\n return `<amazon:effect name=\"${effect}\">${s}</amazon:effect>`;\n }\n /**\n * The audio tag lets you provide the URL for an MP3 file that the\n * Alexa service can play while rendering a response. You can use\n * this to embed short, pre-recorded audio within your service\u2019s\n * response. For example, you could include sound effects alongside\n * your text-to-speech responses, or provide responses using a\n * voice associated with your brand. For more information, see\n * Including Short Pre-Recorded Audio in your Response at\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/handling-requests-sent-by-alexa#audio.\n *\n * Note the following requirements and limitations:\n *\n * * The MP3 must be hosted at an Internet-accessible HTTPS\n * endpoint. HTTPS is required, and the domain hosting the MP3\n * file must present a valid, trusted SSL certificate.\n * Self-signed certificates cannot be used.\n * * The MP3 must not contain any customer-specific or other\n * sensitive information.\n * * The MP3 must be a valid MP3 file (MPEG version 2).\n * * The audio file cannot be longer than ninety (90) seconds.\n * * The bit rate must be 48 kbps. Note that this bit rate gives a\n * good result when used with spoken content, but is generally\n * not a high enough quality for music.\n * * The sample rate must be 16000 Hz.\n *\n * You may need to use converter software to convert your MP3 files\n * to the required codec version (MPEG version 2) and bit rate (48\n * kbps).\n *\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#audio\n *\n * @param srcUrl Specifies the URL for the MP3 file.\n */\n static audio(srcUrl: string): string {\n return `<audio src=\"${srcUrl}\" />`;\n }\n /**\n * Represents a pause in the speech. Set the length of the pause\n * with the strength or time attributes.\n *\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#break\n *\n * @param param0\n */\n static break({ strength, s, ms }: {\n /**\n * none: No pause should be outputted. This can be used to remove a pause that would normally occur (such as after a period).\n *\n * x-weak: No pause should be outputted (same as none).\n *\n * weak: \u2009Treat adjacent words as if separated by a single comma (equivalent to medium).\n *\n * medium: Treat adjacent words as if separated by a single comma.\n *\n * strong: Make a sentence break (equivalent to using the <s> tag).\n *\n * x-strong: Make a paragraph break (equivalent to using the <p> tag).\n */\n strength?: BreakStrengthType;\n /**\n * Duration of the pause in seconds; up to 10 seconds.\n */\n s?: number;\n /**\n * Duration of the pause in milliseconds; up to 10000 milliseconds.\n */\n ms?: number;\n }): string {\n const lc = `${Ssml.lc}${Ssml.break.name}`;\n if (strength) {\n return `<break strength=\"${strength}\"/>`;\n } else if (s || s === 0) {\n const min = 0;\n const max = 10;\n if (s < min) {\n console.warn(`${lc} min: ${min}, actual: ${s} (W: 6ff97060a6734f20b16a81a20d06630e)`);\n s = min;\n } else if (s > max) {\n console.warn(`${lc} max: ${max}, actual: ${s} (W: d57ed120e09c4fcaa19b864bdf9f1fc7)`);\n s = max;\n }\n return `<break time=\"${s}s\"/>`;\n } else if (ms || ms === 0) {\n const min = 0;\n const max = 10000;\n if (ms < min) {\n console.warn(`min: ${min}, actual: ${ms} (W: 0addf6dbab1844a9906bd18a859be3d7)`);\n ms = 0;\n } else if (ms > max) {\n console.warn(`max: ${max}, actual: ${ms} (W: f46b9868ec6d4ef2abd4f2aefe879427)`);\n ms = max;\n }\n return `<break time=\"${ms}ms\"/>`;\n } else {\n throw new Error('Unknown break parameters (E: 1ae569301a354c28a54cc06b58c93b87)');\n }\n }\n\n /**\n * Takes a given text that will be written and provides an alias\n * for it when it's actually spoken.\n *\n * For example, if the written text is the element symbol \"Mg\", then\n * you probably want to verbally say the entire word: \"Magnesium\".\n * In this case, the \"text\" is \"Mg\" and the \"alias\" is \"Magnesium\".\n *\n * @see (@link https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#sub)\n *\n * @param text Written text that will be substituted when spoken, e.g. \"Mg\"\n * @param alias Spoken alias that will be spoken, e.g. \"Magnesium\"\n */\n static sub(text: string, alias: string): string {\n return `<sub alias=\"${alias}\">${text}</sub>`;\n }\n\n /**\n * Similar to <say-as>, this tag customizes the pronunciation of\n * words by specifying the word\u2019s part of speech.\n *\n * @param text Text that requires clarity.\n * @param partOfSpeech Context provided for the given text.\n */\n static w(text: string, partOfSpeech: PartOfSpeech): string {\n return `<w role=\"${partOfSpeech}\">${text}</w>`;\n }\n\n /**\n * Describes how the text should be interpreted. This lets you\n * provide additional context to the text and eliminate any\n * ambiguity on how Alexa should render the text. Indicate how\n * Alexa should interpret the text with the interpret-as attribute.\n *\n * Note that the Alexa service attempts to interpret the provided\n * text correctly based on the text\u2019s formatting even without this\n * tag. For example, if your output speech includes \u201C202-555-1212\u201D,\n * Alexa speaks each individual digit, with a brief pause for each\n * dash. You don\u2019t need to use <say-as interpret-as=\"telephone\"> in\n * this case. However, if you provided the text \u201C2025551212\u201D, but\n * you wanted Alexa to speak it as a phone number, you would need\n * to use <say-as interpret-as=\"telephone\">.\n *\n * @example\n * <speak>\n * Here is a number spoken as a cardinal number:\n * <say-as interpret-as=\"cardinal\">12345</say-as>.\n * Here is the same number with each digit spoken separately:\n * <say-as interpret-as=\"digits\">12345</say-as>.\n * Here is a word spelled out: <say-as interpret-as=\"spell-out\">hello</say-as>\n * </speak>\n *\n * @see\n * https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference#say-as\n */\n static sayAs({ text, interpret, format }: {\n /**\n * Text to specify interpretation.\n */\n text: string;\n /**\n * Value that indicates how text should be interpreted.\n *\n * @see {InterpretAs}\n */\n interpret: InterpretAs;\n /**\n * Only used when interpret-as is set to date. Set to one of\n * the following to indicate format of the date:\n *\n * mdy\n * dmy\n * ymd\n * md\n * dm\n * ym\n * my\n * d\n * m\n * y\n *\n * Alternatively, if you provide the date in YYYYMMDD format,\n * the format attribute is ignored. You can include question\n * marks (?) for portions of the date to leave out. For\n * instance, Alexa would speak <say-as interpret-as=\"date\">????\n * 0922</say-as> as \u201CSeptember 22nd\u201D.\n */\n format?: SayAsDate;\n }): string {\n const lc = `${Ssml.lc}[${Ssml.sayAs.name}]`;\n try {\n if (format) {\n if (interpret !== As.date) {\n throw new Error(`\\`format\\` arg requires (implies) \\`interpret\\` === \"date\" (E: 2a470b25ac284ec4bec9eb3e6a704b6b)`);\n }\n return `<say-as interpret-as=\"${interpret}\" format=\"${format}\">${text}</say-as>`;\n } else {\n return `<say-as interpret-as=\"${interpret}\">${text}</say-as>`;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n}\n", "import { HELPER_LOG_A_LOT } from '../constants.mjs';\nimport { Ssml } from './ssml-helper.mjs';\n\nconst logalot = HELPER_LOG_A_LOT;\n\nexport type LanguageCode = \"en\" | \"de\" | \"en-US\" | \"en-GB\" | \"en-CA\" | \"en-IN\" | \"de-DE\";\nexport const LanguageCode = {\n en: \"en\" as LanguageCode,\n de: \"de\" as LanguageCode,\n enUS: \"en-US\" as LanguageCode,\n enGB: \"en-GB\" as LanguageCode,\n enCA: \"en-CA\" as LanguageCode,\n enIN: \"en-IN\" as LanguageCode,\n deDE: \"de-DE\" as LanguageCode,\n};\n\n/**\n * Interface for each record in the lex data.\n *\n * When specifying `TProps`, be sure it is a flat key: value object. (I think...) Definitely not a circular reference complex object, so maybe any non-circular POCO will work.\n */\nexport interface LexDatum<TProps extends PropsData = PropsData> {\n /**\n * Language of the lexical datum.\n */\n language?: LanguageCode;\n /**\n * Lexical items with the same id are considered alternatives for\n * the equivalent message, e.g. \"Hello\" and \"Howdy\".\n *\n * If you have multiple LexDatums with the same id, then this\n * can differentiate among them to get the _exact_ record.\n *\n * Basically this is an optional unique id, but the data overall\n * is indexed by a non-unique \"id\" string. :nose:? maybe...\n */\n specifier?: string;\n /**\n * Lexical items with the same id are considered alternatives for\n * the equivalent message, e.g. \"Hello\" and \"Howdy\".\n *\n * If you have multiple LexDatums with the same id, then this\n * can define the weighting of chance when selecting one of those\n * alternatives.\n *\n * Must be non-zero. Default weighting is 1.\n *\n * @see Lex.pickDatum\n */\n weighting?: number;\n /**\n * Keywords relating to the datum. You can specify keywords.\n */\n keywords?: string[];\n /**\n * This is the lines of plain text.\n *\n * There should be no ssml tags in here.\n */\n texts?: string[];\n /**\n * This is the ssml equivalent to `text`.\n *\n * Do NOT include any <speak> tags in here.\n */\n ssmls?: string[];\n /**\n * Additional dynamic properties to filter/match against.\n *\n * Use Case:\n *\n * Currently, I'm doing x=123 in keywords, and this is meant to\n * improve upon that.\n */\n props?: TProps;\n}\nexport interface LexGetOptions<TProps extends PropsData = PropsData> {\n /**\n * Language of datum to get.\n */\n language?: LanguageCode;\n /**\n * Specifier of datum to get.\n */\n specifier?: string;\n /**\n * Keywords of datum to get.\n */\n keywords?: string[];\n /**\n * Determines how the `LexGetOptions.keywords` match with filtering\n * data.\n * @see {KeywordMode}\n */\n keywordMode?: KeywordMode;\n /**\n * Index (0-based) into text/ssml of LexDatum to get.\n * If not provided, will return all lines.\n * Basically, use this if you just want a single string from the\n * texts/ssmls array but don't want to duplicate that in a separate\n * data entry.\n *\n * @example If you have texts of [ \"a\", \"b\", \"c\" ], but you just\n * want the \"b\" line, you would pass in a lineIndex of 1.\n */\n lineIndex?: number;\n /**\n * If provided, and if there are multiple lines in datum's\n * text/ssml, then this determines how they are concatenated.\n *\n * @see LexLineConcat\n */\n lineConcat?: LexLineConcat;\n /**\n * If lineConcat is \"delim\", then it will concat using this\n * string as a delimiter. I'll have a default in the `get`\n * function.\n *\n * @see Lex.get\n */\n lineConcatDelim?: string;\n /**\n * How to capitalize the lex item text output when concatenating\n * multiple lines in texts/ssmls.\n *\n * NOTE:\n * I'm not sure if I should make it capitalize the ssml, but\n * my hunch is to NOT do this, since that is supposed to be spoken\n * text.\n *\n * @see LexCapitalize for individual options.\n */\n capitalize?: LexCapitalize;\n /**\n * Template placeholder arguments. Each template in Lex can either\n * be a reference to another Lex datum, e.g. $(hi), or it can be\n * a template placeholder, e.g. $name, $age, $0, $1, etc. It simply\n * has to start with a $ and be followed by one or more word\n * characters ([a-zA-Z_0-9]+, i.e. \\w+).\n *\n * So this javascript object is in the format of\n * `\"placeholder\": \"replacement\"`, e.g.\n *\n * NOTE: If you want different variable replacements for texts and\n * ssmls, then use this config option for the texts and use\n * ssmlVars for the ssmls.\n *\n * @example\n * In Lex data:\n * \"Welcome back, $username!\"\n * Calling code:\n * `lex._('greeting', { vars: { username } })`\n * If the text is and this is called\n * with , then the output\n * would be e.g. \"Welcome back, Cotter!\"\n * (equivalent to `Welcome back, ${username}!`)\n */\n vars?: { [key: string]: string; };\n /**\n * Same as vars option, but will only replace template variables\n * in the `ssmls`.\n */\n ssmlVars?: {\n [key: string]: string;\n };\n /**\n * Additional dynamic properties to filter/match against.\n *\n * Use Case:\n *\n * Currently, I'm doing x=123 in keywords, and this is meant to\n * improve upon that.\n *\n * ## notes\n *\n * These property filters require lambda functions, and as such,\n * these cannot be used from within template references in\n * lex data. see {@link Lex.replaceTemplateRefs}\n */\n props?: PropsFilter<TProps>;\n /**\n * Determines how the props predicate functions.\n * @see PropertyPredicateLevel\n */\n propsMode?: PropsFilterMode;\n /**\n * \"Catchall\" predicate filter that acts on the entire lex datum.\n *\n * So if you don't have a specific filter option in the params list, use this as\n * a backup to just filter against the entire datum in a custom way.\n *\n * ## driving use case\n *\n * I want to reverse get where the `LexDatum.texts` property is exactly a\n * certain value and get the reverse mapping to the \"semantic id\". So a user\n * says some natural language, and I map that back to the possibility(s) for the\n * semantic id of that user word/phrase.\n */\n fnDatumPredicate?: LexDatumPredicate<TProps>,\n}\n/**\n * Contains properties per datum that allow for more complex filtering with\n * two strategies:\n * 1. per property name via a lambda\n * 2. per entire props object via a lambda\n *\n * This is the type in the LexDatum.props property.\n *\n * NOTE: atow this must be just a flat dictionary, i.e. cannot contain nested\n * objects. However, if you want to use FilterPerProps filtering, I believe you\n * can just `any` cast this and do your filtering predicate against the entire\n * props object as you like.\n * */\nexport type PropsData = { [propName: string]: any; };\n/** This is the type used in LexGetOptions.prFilter either per property or per the entire prop data object. */\nexport type PropsFilter<TProps> = FilterPerProp | FilterPerProps<TProps>;\n/** Individual property predicate */\nexport type PropertyPredicate = (propName: string) => boolean;\n/** Filter on individual property level. */\nexport type FilterPerProp = { [propName: string]: PropertyPredicate; };\n/** Filter at the entire props object level (`LexDatum.props`). */\nexport type FilterPerProps<TProps> = (props: TProps) => boolean;\n\nexport interface LexFindOptions<TProps extends PropsData = PropsData> {\n fnDatumPredicate?: LexDatumPredicate<TProps>,\n}\nexport type LexFindResults<TProps extends PropsData = PropsData> = { [id: string]: LexDatum<TProps>[] }\n\n/**\n * filter against the entier lex datum entry. see the LexGet options.\n */\nexport type LexDatumPredicate<TProps extends PropsData> = (value: LexDatum<TProps>) => boolean;\n\n/**\n * keywords are used to filter lex items. this sets how those keywords are\n * interpreted.\n */\nexport type KeywordMode = \"any\" | \"all\" | \"none\";\n/**\n * keywords are used to filter lex items. this sets how those keywords are\n * interpreted.\n */\nexport const KeywordMode = {\n /** Any of the keywords must match to return a lex result. */\n any: \"any\" as KeywordMode,\n /** All of the keywords must match to return a lex result. */\n all: \"all\" as KeywordMode,\n /** Only return results that do NOT include any of the keywords. */\n none: \"none\" as KeywordMode,\n};\n\nexport type PropsFilterMode = \"prop\" | \"props\";\nexport const PropertyPredicateLevel = {\n /**\n * Predicate acts upon individual properties.\n * So you'll pass an object in with prop key and a predicate(s).\n *\n * Check out advanced unit tests for more concrete examples.\n *\n * @example props: { id: x => x === \"id2\", color: x => x === \"orange\" }\n */\n prop: \"prop\" as PropsFilterMode,\n /**\n * Predicate acts upon the datum's entire props object.\n * So you'll pass a single predicate that is the entire props\n * object, i.e. datum[props].\n *\n * Check out advanced unit tests for more concrete examples.\n *\n * @example { props: (p: PropsData) => { return p && p.id && p.id === \"id1\"; }, propsMode: \"props\"\n */\n props: \"props\" as PropsFilterMode,\n};\n\n// export type LexResultType = \"text\" | \"ssml\" | \"obj\";\n\n/**\n * Result object when using `Lex._`\n *\n * @see Lex\n * @see Lex.get\n */\nexport interface LexResultObj<TProps extends PropsData = PropsData> {\n /**\n * The text output of the single datum that was picked.\n */\n text: string;\n /**\n * The ssml output of the single datum that was picked.\n */\n ssml: string;\n /**\n * The single raw datum that was picked.\n */\n datum: LexDatum<TProps>;\n /**\n * All of the data that matched the given params (specifier,\n * keywords, language, etc.)\n */\n rawData: LexDatum<TProps>[];\n}\n\nexport type LexCapitalize = \"upperfirst\" | \"uppereach\" | \"lowerfirst\" | \"lowereach\" | \"none\";\nexport const LexCapitalize = {\n /**\n * Uppercase the first letter of only the first line in texts/ssmls.\n */\n upperfirst: \"upperfirst\" as LexCapitalize,\n /**\n * Uppercase the first letter of each line in texts/ssmls.\n */\n uppereach: \"uppereach\" as LexCapitalize,\n /**\n * Lowercase the first letter of only the first line in texts/ssmls.\n */\n lowerfirst: \"lowerfirst\" as LexCapitalize,\n /**\n * Lowercase the first letter of each line in texts/ssmls.\n */\n lowereach: \"lowereach\" as LexCapitalize,\n /**\n * Leave the casing as-is for texts/ssmls.\n */\n none: \"none\" as LexCapitalize,\n};\n\nexport type LexLineConcat = \"paragraph\" | \"sentence\" | \"newline\" | \"delim\";\nexport const LexLineConcat = {\n /**\n * Each line will be combined into a single string of paragraphs.\n * @example\n * [\"Line 1.\", \"Line 2.\"] will become\n * if text: \"Line 1.\\n\\nLine 2.\"\n * if ssml: \"<p>Line 1.</p><p>Line 2.</p>\"\n */\n p: \"paragraph\" as LexLineConcat,\n paragraph: \"paragraph\" as LexLineConcat,\n /**\n * Each line will be combined into a single string of sentences.\n * @example\n * [\"Line 1.\", \"Line 2.\"] will become\n * if text: \"Line 1. Line 2.\"\n * if ssml: \"<s>Line 1</s><s>Line 2</s>\"\n */\n s: \"sentence\" as LexLineConcat,\n sentence: \"sentence\" as LexLineConcat,\n /**\n * Each line will be combined into a single string with new\n * line feeds between each line.\n *\n * Note: For Ssml, this is the same as \"paragraph\".\n *\n * @example\n * [\"Line 1.\", \"Line 2.\"] will become\n * if text: \"Line 1.\\nLine 2.\"\n * if ssml: \"<p>Line 1.</p><p>Line 2.</p>\"\n */\n n: \"newline\" as LexLineConcat,\n newline: \"newline\" as LexLineConcat,\n /**\n * Each line will be combined into a single string with each\n * line delimited by the delimiter specified in the function.\n *\n * @example\n * [\"Line 1.\", \"Line 2.\"] with delim | will become\n * if text: \"Line 1.|Line 2.\"\n * if ssml: \"Line 1.|Line 2.\"\n */\n delim: \"delim\" as LexLineConcat,\n};\nexport type LexData<TProps extends PropsData = PropsData> = {\n [key: string]: LexDatum<TProps>[];\n};\n\n/**\n * These options control mostly the default behavior for filtering lex results\n * when consuming via the `Lex._(someIdentifier, opts)` call. When you don't\n * specify in the `opts` how to filter, these values will be used.\n *\n * These options are in the constructor of the {@link Lex} class.\n */\nexport interface LexCtorOpts {\n /**\n * This is the language that your data will default to.\n *\n * This means that entries defined in the Lex data that do not\n * have an explicit 'language' set will be interpreted as this\n * language.\n *\n * So basically, if you're an American with American data, leave\n * this as en-US. If you're a German speaker writing a skill\n * that is primarily targeted at a German-speaking audience,\n * then set this to de-DE and you don't need to explicitly\n * set each entry to this.\n *\n * Then, when you go to translate into other languages, you can\n * add on the explicit language markers in data. The overall\n * mechanism allows you to skip this for the first language\n * you write the skill in.\n *\n * @see requestLanguage\n */\n defaultLanguage?: LanguageCode;\n /**\n * This is the language that is coming in from the request.\n *\n * @see defaultLanguage\n */\n requestLanguage?: LanguageCode;\n /**\n * Default setting when concatenating lines. This will depend on how most of\n * your data is structured. For example, it's designed so that you input\n * your data separated by paragraphs, so the concat would be \"paragraph\".\n * But if you already have data with <p> tags in your ssml, then you may\n * want to set this to \"delim\" and do your own interpretation of using the\n * multiple strings for the data.\n *\n * Defaults to delim & \"\" because most of the time, I find I\n * just have a single line and want the single thing returned.\n * This helps with templating, chunking, etc.\n */\n defaultLineConcat?: LexLineConcat;\n /**\n * Default delimiter used when using `lineConcatDelim`.\n *\n * Defaults to delim & \"\" because most of the time, I find I just have a\n * single line and want the single thing returned. This helps with\n * templating, chunking, etc.\n */\n defaultDelim?: string;\n /**\n * Default capitalization action when getting texts/ssmls.\n */\n defaultCapitalize?: LexCapitalize;\n /**\n * When using keyword filtering, this is the default mode to be used\n * when not explicitly set in the lex consumer.\n */\n defaultKeywordMode?: KeywordMode;\n /**\n * When using props filtering, this is the default mode to be used\n * when not explicitly set in the lex consumer.\n */\n defaultPropsMode?: PropsFilterMode;\n}\n\n\n\n/**\n * Lex is a helper for your lexical data, i.e. the things that you get\n * Alexa to say. This can be used for i18n, but really it's a broader\n * helper to create more dynamic speech/text for Alexa to say and\n * present via cards.\n *\n * I am making this after learning my lessons with creating dynamic,\n * alternative-laden text and/or ssml generation for use with both\n * Alexa's speech, as well as outputting plain text to\n * cards. I'm designing it to be (actually) simple to use, but with\n * robustness allowed the more you become comfortable with it.\n *\n * Simple Usage\n *\n * To use it, you simply init what you want her to be able to say.\n * Then, when you want to create her speech, you call `text` or `ssml`\n * and pass in your options, the primary one being the `id`.\n *\n * For example, you could define the following data:\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ]}\n ]\n }\n ```\n * To access this, you would call `Lex._('hi').text` to simply get the\n * plain text entry for \"hi\".\n *\n * Alternatives\n *\n * But there are a LOT of ways to say \"hi\", and this is the primary\n * reason for using Lex: Alternatives. With Lex, multiple items with\n * the same id are considered alternatives.\n *\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ] },\n { texts: [ \"Hello\" ] },\n { texts: [ \"Howdy\" ] }\n ]\n }\n ```\n * Again, to access this, you would call the same line:\n * `Lex._('hi').text\n *\n * So by using the _same_ calling code, you could get any one of these\n * texts as _alternatives_ for the \"hi\" lex datum. This is a huge\n * difference between natural voice interaction and computer UI as we\n * have known it up to now.\n *\n * If you want to get really fancy (looking forward to AI/ML), you can\n * weight the various alternatives, for example if you want to only\n * say \"Howdy\" a small percentage of the time. You could define this as follows:\n *\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ] },\n { texts: [ \"Hello\" ] },\n { texts: [ \"Howdy\" ], weighting: 0.2 }\n ]\n }\n ```\n * Again, there is _no_ change to the calling code. This really allows\n * for a wonderful layer of dynamicism, and is easy to do.\n *\n * Internationalization (i18n)\n *\n * You can have your text be localized, but not worry about it to start\n * off with. It's _implicit_ i18n. So the above examples are actually\n * not really attached to any language, even though I'm writing in\n * English (en-US). This is because the i18n aspect relies on both the\n * data and the retrieval of the data via the `language` param option.\n *\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ] },\n { texts: [ \"Hello\" ] },\n { texts: [ \"Howdy\" ], weighting: 0.2 },\n { texts: [ \"Cheers\" ], language: \"en-GB\" },\n { texts: [ \"Guten Tag\" ], language: \"de-DE\" }\n ]\n }\n ```\n/**\n * Lex is a helper for your lexical data, i.e. the things that you get\n * Alexa to say. This can be used for i18n, but really it's a broader\n * helper to create more dynamic speech/text for Alexa to say and\n * present via cards.\n *\n * I am making this after learning my lessons with creating dynamic,\n * alternative-laden text and/or ssml generation for use with both\n * Alexa's speech, as well as outputting plain text to\n * cards. I'm designing it to be (actually) simple to use, but with\n * robustness allowed the more you become comfortable with it.\n *\n * Simple Usage\n *\n * To use it, you simply init what you want her to be able to say.\n * Then, when you want to create her speech, you call `text` or `ssml`\n * and pass in your options, the primary one being the `id`.\n *\n * For example, you could define the following data:\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ]}\n ]\n }\n ```\n * To access this, you would call `Lex._('hi').text` to simply get the\n * plain text entry for \"hi\".\n *\n * Alternatives\n *\n * But there are a LOT of ways to say \"hi\", and this is the primary\n * reason for using Lex: Alternatives. With Lex, multiple items with\n * the same id are considered alternatives.\n *\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ] },\n { texts: [ \"Hello\" ] },\n { texts: [ \"Howdy\" ] }\n ]\n }\n ```\n * Again, to access this, you would call the same line:\n * `Lex._('hi').text\n *\n * So by using the _same_ calling code, you could get any one of these\n * texts as _alternatives_ for the \"hi\" lex datum. This is a huge\n * difference between natural voice interaction and computer UI as we\n * have known it up to now.\n *\n * If you want to get really fancy (looking forward to AI/ML), you can\n * weight the various alternatives, for example if you want to only\n * say \"Howdy\" a small percentage of the time. You could define this as follows:\n *\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ] },\n { texts: [ \"Hello\" ] },\n { texts: [ \"Howdy\" ], weighting: 0.2 }\n ]\n }\n ```\n * Again, there is _no_ change to the calling code. This really allows\n * for a wonderful layer of dynamicism, and is easy to do.\n *\n * Internationalization (i18n)\n *\n * You can have your text be localized, but not worry about it to start\n * off with. It's _implicit_ i18n. So the above examples are actually\n * not really attached to any language, even though I'm writing in\n * English (en-US). This is because the i18n aspect relies on both the\n * data and the retrieval of the data via the `language` param option.\n *\n ```\n const data: LexData = {\n 'hi': [\n { texts: [ \"Hi\" ] },\n { texts: [ \"Hello\" ] },\n { texts: [ \"Howdy\" ], weighting: 0.2 },\n { texts: [ \"Cheers\" ], language: \"en-GB\" },\n { texts: [ \"Guten Tag\" ], language: \"de-DE\" }\n ]\n }\n ```\n *\n * You can get at these languages multiple ways:\n *\n * 1) Choose the language when instantiating Lex.\n * `let lex = new Lex(data, \"de-DE\");`\n * Now, when you call `lex._(...)`, you will only return German\n * data.\n * 2) Override the default language upon calling for data:\n * `lex._('hi', { language: \"en-US\" }).text;`\n */\nexport class Lex<TProps extends PropsData = PropsData> {\n protected lc: string = `[${Lex.name}]`;\n\n data: LexData<TProps>;\n defaultLanguage: LanguageCode;\n defaultLineConcat: LexLineConcat;\n /**\n * Defaults to delim & \"\" because most of the time, I find I\n * just have a single line and want the single thing returned.\n * This helps with templating, chunking, etc.\n *\n * BREAKING CHANGE: This formerly defaulted to paragraphs, as\n * I thought lines would mean paragraphs. No longer the case.\n */\n defaultDelim: string;\n defaultCapitalize: LexCapitalize;\n /**\n * This is the language that is coming in from the request.\n *\n * @see defaultLanguage\n */\n requestLanguage: LanguageCode;\n defaultKeywordMode: KeywordMode;\n defaultPropsMode: PropsFilterMode;\n\n constructor(\n /**\n * This is the initial lexical data that you want Alexa to be able to\n * say. You can always change this dynamically at runtime as well.\n */\n data: LexData<TProps>,\n /** optional opts */\n {\n /**\n * This is the language that your data will default to.\n * If a language isn't specified in `get`, `text`, or `ssml`, then this is used.\n *\n * This means that entries defined in the Lex data that do not\n * have an explicit 'language' set will be interpreted as this\n * language.\n *\n * So basically, if you're an American with American data, leave\n * this as en-US. If you're a German speaker writing a skill\n * that is primarily targeted at a German-speaking audience,\n * then set this to de-DE and you don't need to explicitly\n * set each entry to this.\n *\n * Then, when you go to translate into other languages, you can\n * add on the explicit language markers in data. The overall\n * mechanism allows you to skip this for the first language\n * you write the skill in.\n *\n * @see requestLanguage\n */\n defaultLanguage = \"en-US\",\n requestLanguage = \"en-US\",\n /**\n * Defaults to delim & \"\" because most of the time, I find I\n * just have a single line and want the single thing returned.\n * This helps with templating, chunking, etc.\n *\n * BREAKING CHANGE: This formerly defaulted to paragraphs, as\n * I thought lines would mean paragraphs. No longer the case.\n */\n defaultLineConcat = LexLineConcat.delim,\n /**\n * Defaults to delim & \"\" because most of the time, I find I\n * just have a single line and want the single thing returned.\n * This helps with templating, chunking, etc.\n *\n * BREAKING CHANGE: This formerly defaulted to paragraphs, as\n * I thought lines would mean paragraphs. No longer the case.\n */\n defaultDelim = \"\",\n defaultCapitalize = \"none\",\n defaultKeywordMode = \"any\",\n defaultPropsMode = \"prop\",\n }: LexCtorOpts\n ) {\n if (!data) { throw new Error(`data required (E: 2f8db30fa9d71d76db616ab110392c22)`); }\n this.data = data;\n this.defaultLanguage = defaultLanguage ?? \"en-US\";\n this.defaultLineConcat = defaultLineConcat ?? LexLineConcat.delim;\n this.defaultDelim = defaultDelim ?? \"\";\n this.defaultCapitalize = defaultCapitalize ?? \"none\";\n this.requestLanguage = requestLanguage ?? \"en-US\";\n this.defaultKeywordMode = defaultKeywordMode ?? \"any\";\n this.defaultPropsMode = defaultPropsMode ?? \"prop\";\n }\n\n /**\n * Gets a string or array of strings of text or ssml.\n * Builds the string or obj depending on the passed in options.\n *\n * NOTE: You'll probably want to actually use the `text` or `ssml`\n * functions instead of this one.\n *\n * @param id Lexical items with the same id are considered alternatives for the equivalent message, e.g. \"Hello\" and \"Howdy\".\n * @see LexGetOptions\n */\n get(\n id: string,\n {\n language = this.requestLanguage,\n specifier,\n keywords, keywordMode = this.defaultKeywordMode,\n lineIndex,\n lineConcat = this.defaultLineConcat, lineConcatDelim = this.defaultDelim,\n capitalize = this.defaultCapitalize,\n vars, ssmlVars,\n props, propsMode = this.defaultPropsMode,\n fnDatumPredicate,\n }: LexGetOptions<TProps> = {\n // simplest case default options\n language: this.requestLanguage,\n keywordMode: this.defaultKeywordMode,\n lineConcat: this.defaultLineConcat,\n lineConcatDelim: this.defaultDelim,\n capitalize: this.defaultCapitalize,\n propsMode: this.defaultPropsMode,\n }): LexResultObj<TProps> | null {\n const lc = `${this.lc}[${this.get.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e4e76a6bb301010fc13cf4456efcdc22)`); }\n\n let lexData = this.data[id];\n\n if (!lexData) { throw new Error(`Data id not found: ${id} (E: 4a79897167714dd5a34df77953072aaf)`); }\n\n lexData = this.filterLexData({\n lexData,\n language, specifier,\n keywords, keywordMode,\n props: props as PropsFilter<TProps>, propsMode,\n fnDatumPredicate,\n });\n if (lexData.length === 0) {\n // no data found matching filtering.\n // just return null and do not error.\n return null;\n }\n const lexDatum = this.pickDatum(lexData)!;\n let textLines = this.extractLines({ lexDatum, resultAs: \"text\", lineIndex });\n textLines = this.replaceTemplateRefs({ lines: textLines, resultAs: \"text\" });\n // Replace vars after references, so all text is fully\n // expanded first.\n textLines = this.replaceTemplateVars({ lines: textLines, vars: vars });\n textLines = this.capitalizeLines({ lines: textLines, resultAs: \"text\", capitalize });\n const text = this.concatLines({\n lines: textLines,\n lineType: \"text\",\n lineConcat,\n lineConcatDelim\n });\n let ssmlLines = this.extractLines({ lexDatum, resultAs: \"ssml\", lineIndex });\n ssmlLines = this.replaceTemplateRefs({ lines: ssmlLines, resultAs: \"ssml\" });\n // Replace vars after references, so all text is fully\n // expanded first.\n ssmlLines = this.replaceTemplateVars({ lines: ssmlLines, vars: ssmlVars || vars });\n ssmlLines = this.capitalizeLines({ lines: ssmlLines, resultAs: \"ssml\", capitalize });\n const ssml = this.concatLines({ lines: ssmlLines, lineType: \"ssml\", lineConcat, lineConcatDelim });\n\n return { text, ssml, datum: lexDatum, rawData: lexData };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Does a reverse lookup for lex data ids that correspond to the find\n * criteria.\n *\n * @returns array of data ids that have at least one LexDatum entry that matches criteria.\n */\n find({ fnDatumPredicate }: LexFindOptions<TProps>): LexFindResults<TProps> | null {\n const lc = `${this.lc}[${this.find.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 35e26d234ca2d0e987b39ee939f29c22)`); }\n if (!fnDatumPredicate) { throw new Error(`only fnDatumPredicate implemented atow (E: 8c8babd2fa6fc4cb223b7b8c10ad5c22)`); }\n\n const results: LexFindResults<TProps> = {};\n\n const ids = Object.keys(this.data);\n for (let i = 0; i < ids.length; i++) {\n const id = ids[i];\n const matchingDatums = this.data[id].filter(d => fnDatumPredicate(d));\n if (matchingDatums.length > 0) { results[id] = matchingDatums; }\n }\n\n return Object.keys(results).length > 0 ? results : null;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * This is the original single function. it is just for backwards compatibility at this point.\n * Probably not needed...\n *\n * @deprecated\n */\n _(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n\n // #region syntactic sugar calls for `get`\n\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n getVariant(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n variant(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n getTranslation(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n translate(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n getSynonym(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n synonym(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n getI18n(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n /**\n * just syntactic sugar for {@link Lex.get} .\n */\n i18n(id: string, opts: LexGetOptions<TProps>): LexResultObj<TProps> | null {\n return this.get(id, opts);\n }\n\n // #endregion syntactic sugar calls for `get`\n\n /**\n * Pulls out lines from the datum, based on the what is wanted\n * and what exists in the data.\n *\n * For example, you may be trying to extract text but only ssml\n * is defined in the data. So you'll have to strip the ssml and\n * return that. Or if you want ssml and only text exists in the\n * data, then you'll simply return the texts.\n *\n * If you only want a single line out of multiple strings in the\n * texts/ssmls array, then use lineIndex.\n *\n * @param param0 info\n */\n private extractLines({\n lexDatum,\n resultAs,\n lineIndex\n }: {\n lexDatum: LexDatum<TProps>,\n resultAs: \"text\" | \"ssml\",\n lineIndex: number | undefined,\n }): string[] {\n const lc = `${this.lc}[${this.extractLines.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0c21a7ed7c1b56251f39342380c47922)`); }\n\n // ensure that either texts or ssmls is defined in data\n if ((!lexDatum.texts || lexDatum.texts.length === 0) &&\n (!lexDatum.ssmls || lexDatum.ssmls.length === 0)) {\n throw new Error(`Invalid lexDatum. Datum texts and ssmls are both undefined. lexDatum: ${JSON.stringify(lexDatum)}.`);\n }\n // let lines;\n let useLineIndex = lineIndex || lineIndex === 0;\n if (resultAs === \"text\" &&\n lexDatum.texts && lexDatum.texts.length > 0) {\n // text wanted, text defined in data\n return useLineIndex ?\n [lexDatum.texts[lineIndex!]] :\n lexDatum.texts;\n } else if (resultAs === \"text\") {\n // text wanted, but no text defined in data\n console.warn(`building text lines from ssml (W: cfb59a05efda475ab7511acc659a5ee3)`);\n return useLineIndex ?\n [Ssml.stripSsml(lexDatum.ssmls![lineIndex!])] :\n lexDatum.ssmls!.map(ssml => Ssml.stripSsml(ssml));\n } else if (lexDatum.ssmls && lexDatum.ssmls.length > 0) {\n // ssml wanted, ssml defined in data\n return useLineIndex ?\n [lexDatum.ssmls[lineIndex!]] :\n lexDatum.ssmls;\n } else {\n // ssml wanted, but no ssml defined in data\n return useLineIndex ?\n [lexDatum.texts![lineIndex!]] :\n lexDatum.texts!;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Replaces any embedded template variables, e.g. $name, $0, etc.\n * Note the format is \"$\" proceeded by any word characters\n * ([a-zA-Z0-9_]).\n *\n * This is different than template references.\n *\n * @see {replaceTemplateRefs}\n */\n private replaceTemplateVars({\n lines,\n vars,\n }: {\n lines: string[],\n vars?: { [key: string]: string; },\n }): string[] {\n const lc = `${this.lc}[${this.replaceTemplateVars.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: a756e7603d03d427c60c202cb4f6dd22)`); }\n\n let replaceVarsSingleLine = (line: string) => {\n let varNames = Object.keys(vars || {});\n if (logalot) { console.log(`${lc} varNames: ${JSON.stringify(varNames)} (I: d9351cf582420b35eb3eceb923e64f22)`); }\n return varNames.reduce((l, varName) => {\n if (logalot) { console.log(`${lc} varName: ${varName} (I: 8c0e4261972945d2bb4624efad14870b)`); }\n return l.replace(new RegExp('\\\\$' + varName, \"g\"), vars![varName]);\n }, line);\n };\n if (vars) {\n return lines.map(line => replaceVarsSingleLine(line));\n } else {\n return lines;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n /**\n * Replaces any embedded template references, e.g. $(hi). Note the\n * parenthesis around \"hi\". This means it is a reference to another lex\n * datum.\n *\n * This is different than template variables, e.g. $name, $0, etc.\n *\n * The template refs can be recursive, i.e. datum A can include a ref to\n * datum B which includes a template to datum C. But these cannot be\n * self-referencing, i.e. C cannot then include a reference back to A.\n *\n * Template refs CANNOT work with props for filtering, as these require\n * lambda functions.\n *\n * @see {replaceTemplateVars}\n */\n private replaceTemplateRefs({\n lines,\n resultAs,\n }: {\n /**\n * source lines from data\n */\n lines: string[],\n /**\n * how do you want the lines back?\n */\n resultAs: \"ssml\" | \"text\",\n }): string[] {\n const lc = `${this.lc}[${this.replaceTemplateRefs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 548949b651bbec84de5b25f3c01cf422)`); }\n const regex = /\\$\\([\\w-]+\\|?[\\w-|\\{\\}:'\"\\s,\\[\\].,<>]+\\)/;\n\n let replaceRefsSingleLine: (l: string) => any = (line: string) => {\n let match = regex.exec(line);\n if (match) {\n let template = match[0];\n // strip the $()\n template = template.substring(2, template.length - 1);\n // id|options\n const idAndOptions = template.split('|');\n const id = idAndOptions[0];\n const options: LexGetOptions<TProps> = idAndOptions.length === 2 ?\n JSON.parse(idAndOptions[1]) as LexGetOptions<TProps> :\n {};\n if (!options.lineConcat) {\n options.lineConcat = LexLineConcat.delim;\n options.lineConcatDelim = \"\";\n }\n const replacementResult = this.get(id, options);\n const replacement = resultAs === \"text\" ?\n replacementResult!.text :\n replacementResult!.ssml;\n line = line.replace(regex, replacement);\n // recursively call if more templates in line\n return regex.test(line) ?\n replaceRefsSingleLine(line) :\n line;\n } else {\n return line;\n }\n };\n\n return lines.map(line => replaceRefsSingleLine(line));\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Capitalizes the given lines depending on the given\n * capitalize options.\n *\n * @param param0\n */\n private capitalizeLines({\n lines,\n resultAs,\n capitalize,\n }: {\n lines: string[],\n resultAs: \"ssml\" | \"text\",\n capitalize: LexCapitalize,\n }) {\n const lc = `${this.lc}[${this.capitalizeLines.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b0ec8263fd94c68ee53fdf61534c8322)`); }\n\n const replaceAt = (s: string, i: number, replacement: string) => {\n // todo: change substr to use substring\n return s.substr(0, i) +\n replacement +\n s.substr(i + replacement.length);\n };\n const upperText = (line: string) => {\n if (line === \"\") {\n return \"\";\n }\n // Thanks https://paulund.co.uk/capitalize-first-letter-string-javascript\n return line.charAt(0).toUpperCase() + line.slice(1);\n };\n const upperSsml = (line: string) => {\n if (line === \"\") {\n return \"\";\n }\n if (line.charAt(0) === \"<\") {\n let iFirstLetter = line.indexOf(\">\") + 1;\n return replaceAt(line, iFirstLetter, line[iFirstLetter].toUpperCase());\n } else {\n return upperText(line);\n }\n };\n const lowerText = (line: string) => {\n if (line === \"\") {\n return \"\";\n }\n // Thanks https://paulund.co.uk/capitalize-first-letter-string-javascript\n return line.charAt(0).toLowerCase() + line.slice(1);\n };\n const lowerSsml = (line: string) => {\n if (line === \"\") {\n return \"\";\n }\n if (line.charAt(0) === \"<\") {\n let iFirstLetter = line.indexOf(\">\") + 1;\n return replaceAt(line, iFirstLetter, line[iFirstLetter].toLowerCase());\n } else {\n return lowerText(line);\n }\n };\n const firstLine = lines[0];\n switch (capitalize) {\n case LexCapitalize.upperfirst:\n lines[0] =\n resultAs === \"text\" ?\n upperText(firstLine) :\n upperSsml(firstLine);\n return lines;\n case LexCapitalize.uppereach:\n return lines.map(l => {\n return resultAs === \"text\" ?\n upperText(l) :\n upperSsml(l);\n });\n case LexCapitalize.lowerfirst:\n lines[0] =\n resultAs === \"text\" ?\n lowerText(firstLine) :\n lowerSsml(firstLine);\n return lines;\n case LexCapitalize.lowereach:\n return lines.map(l => {\n return resultAs === \"text\" ?\n lowerText(l) :\n lowerSsml(l);\n });\n case LexCapitalize.none:\n return lines;\n default:\n throw new Error(`Unknown LexCapitalize: ${capitalize}`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Concatenates lines depending on given params.\n *\n * @param param0\n */\n private concatLines({\n lines,\n lineType,\n lineConcat,\n lineConcatDelim\n }: {\n lines: string[],\n lineType: \"ssml\" | \"text\",\n lineConcat: LexLineConcat,\n lineConcatDelim: string,\n }): string {\n const lc = `${this.lc}[${this.concatLines.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 59e0a7b89457283751b376295b61bb22)`); }\n\n const firstLine = lines[0];\n // This used in both LexLineConcat.p and .n\n const concatSsmlP = () => {\n const pTag = \"<p>\";\n if (firstLine.length < pTag.length ||\n firstLine.substring(0, pTag.length).toLowerCase() !== pTag) {\n return lines.map(l => `<p>${l}</p>`).join('');\n } else {\n // First line starts with <p> so\n // we will simply concat all lines,\n // assuming the user has wrapped all lines.\n return lines.join('');\n }\n };\n switch (lineConcat) {\n case LexLineConcat.p:\n if (lineType === \"text\") {\n return lines.join(\"\\n\\n\");\n } else {\n return concatSsmlP();\n }\n case LexLineConcat.s:\n if (lineType === \"text\") {\n // Append period if not in data.\n // e.g. Data may just be \"hello\" and we want to\n // make it a sentence by appending \".\"\n return lines.map(l => {\n let lastChar = l.substring(l.length - 1);\n return [\".\", \"!\", \"?\"].includes(lastChar) ?\n l :\n l + \".\";\n }).join(' ');\n } else {\n const sTag = \"<s>\";\n if (firstLine.length < sTag.length ||\n firstLine.substring(0, sTag.length).toLowerCase() !== sTag) {\n return lines.map(l => `<s>${l}</s>`).join('');\n } else {\n // First line starts with <s> so\n // we will simply concat all lines,\n // assuming the user has wrapped all lines.\n return lines.join('');\n }\n }\n case LexLineConcat.n:\n if (lineType === \"text\") {\n return lines.join('\\n');\n } else {\n return concatSsmlP();\n }\n case LexLineConcat.delim:\n return lines.join(lineConcatDelim);\n default:\n throw new Error(`Unknown LexLineConcat: ${lineConcat} (E: e19f9c44217f4eb5999e2085d3f77b5c)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Filters the given lexData per the language, specifier,\n * and keywords.\n *\n * @param param0 Filter params\n * @returns filtered datum array\n */\n private filterLexData({\n lexData,\n language,\n specifier,\n keywords, keywordMode,\n props, propsMode,\n fnDatumPredicate,\n }: {\n lexData: LexDatum<TProps>[],\n language: LanguageCode,\n specifier: string | undefined,\n keywords: string[] | undefined,\n keywordMode: KeywordMode,\n props: PropsFilter<TProps> | undefined,\n propsMode: PropsFilterMode,\n fnDatumPredicate: LexDatumPredicate<TProps> | undefined,\n }): LexDatum<TProps>[] {\n const lc = `${this.lc}[${this.filterLexData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1091755e98f390954d296575d1096722)`); }\n let result = lexData.concat(); // makes a copy\n if (language) {\n result = this.filterLanguage(result, language);\n }\n if (specifier) {\n result = result.filter(d => d.specifier && d.specifier === specifier);\n }\n if (keywords && keywords.length > 0) {\n // Datum must contain keywords that overlap with given\n // keywords args.\n keywords = keywords.map(kw => kw.toLocaleLowerCase())!;\n switch (keywordMode) {\n case \"any\":\n result =\n result.filter(d => d.keywords &&\n d.keywords.some(kwDatum => keywords!\n .map(kwArg => kwArg.toLocaleLowerCase())\n .some(kwArg => kwDatum === kwArg)));\n break;\n case \"all\":\n result = result.filter(d => {\n let dKeywords = (d.keywords || [])\n .map(x => x.toLocaleLowerCase());\n return keywords!.every(kwArg => dKeywords.includes(kwArg));\n });\n break;\n case \"none\":\n result = result.filter(d => {\n let dKeywords = (d.keywords || [])\n .map(x => x.toLocaleLowerCase());\n return keywords!.every(kwArg => !dKeywords.includes(kwArg));\n });\n break;\n default:\n console.error(`${lc} Unknown keywordMode: ${keywordMode}`);\n break;\n }\n }\n if (props) {\n result = this.filterProps({ result, props, propsMode });\n }\n if (fnDatumPredicate) {\n result = result.filter(x => fnDatumPredicate(x));\n }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * executes the property filter on the given (intermediate) result.\n */\n private filterProps({\n result,\n props,\n propsMode\n }: {\n result: LexDatum<TProps>[],\n /**\n * Filters either per prop or per the entire props object.\n *\n * Here are how they're defined atow. (see them for reference)\n * PropsData = { [propName: string]: string; };\n * PropsFilter<TProps> = FilterPerProp | FilterPerProps<TProps>;\n * PropertyPredicate = (propName: string) => boolean;\n * FilterPerProp = { [propName: string]: PropertyPredicate; };\n * FilterPerProps<TProps> = (props: TProps) => boolean;\n */\n props: PropsFilter<TProps>,\n propsMode: PropsFilterMode,\n }): LexDatum<TProps>[] {\n // not within a try...catch because used in a tight loop within another fn that catches it\n if (propsMode === \"prop\") {\n const propsFilter = props as FilterPerProp;\n return result.filter(d => {\n return Object.keys(propsFilter).every((propName: string) => {\n const propFn = propsFilter[propName];\n const dPropValue: any = !!d.props ? d.props[propName] as any : undefined;\n return propFn(dPropValue);\n });\n });\n } else if (propsMode === \"props\") {\n let propsFn = props as FilterPerProps<TProps>;\n return result.filter(d => propsFn(d.props as TProps));\n } else {\n throw new Error(`Invalid propsMode: ${propsMode} (E: 216a926144d2436a900b81ffe0aa6174)`);\n }\n }\n\n private filterLanguage(result: LexDatum<TProps>[], language: string): LexDatum<TProps>[] {\n result = result.filter(d =>\n // explicit language given\n (d.language && d.language === language) ||\n // default language is 2 letters and matches\n (!d.language &&\n this.defaultLanguage.length === 2 &&\n language.startsWith(this.defaultLanguage)) ||\n // default language is 4 letters and is equal\n (!d.language && this.defaultLanguage === language));\n return result;\n }\n\n /**\n * Picks a randomesque datum from the given lexData, taking into\n * account the weighting of each datum.\n *\n * @param lexData Filtered lexData from which to choose a random item, per the item's weighting\n *\n * @see LexDatum.weighting\n */\n private pickDatum(lexData: LexDatum<TProps>[]): LexDatum<TProps> | null {\n const lc = `${this.lc}[${this.pickDatum.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f95c8585a8274f78a1e724d6ab58ff22)`); }\n if (!lexData) { throw new Error(`lexData required (E: cedb1fd9b67856c33b41c7dd4aab7c22)`); }\n if (lexData.length === 0) {\n return null;\n } else if (lexData.length === 1) {\n return lexData[0];\n } else {\n const totalWeight = lexData.reduce((agg, item) => {\n return agg + (item.weighting ? item.weighting : 1);\n }, 0);\n // normalized random number\n const randomNumber = Math.random() * totalWeight;\n let result: LexDatum<TProps> | null = null;\n lexData.reduce((runningWeight, item) => {\n if (result) {\n // already got a result\n return -1;\n } else {\n runningWeight += (item.weighting ? item.weighting : 1);\n if (runningWeight >= randomNumber) { result = item; }\n return runningWeight;\n }\n }, 0);\n return result;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n\n/**\n * Contains a unit of speech, represented either by text, ssml, or both.\n * */\nexport interface OutputSpeech {\n /**\n * A string containing the type of output speech to render. Valid types are:\n * \"PlainText\": Indicates that the output speech is defined as plain text.\n * \"SSML\": Indicatesthat the output speech is text marked up with SSML.\n */\n type: OutputSpeechType;\n /** A string containing the speech to render to the user. Use this when type is \"PlainText\" */\n text?: string;\n /** A string containing text marked up with SSML to render to the user. Use this when type is \"SSML\" */\n ssml?: string;\n}\n\n/**\n * output speech is either text or ssml.\n */\nexport declare type OutputSpeechType = 'PlainText' | 'SSML';\nexport declare const OutputSpeechType: {\n /**\n * Indicates that the output speech is defined as plain text.\n */\n PlainText: OutputSpeechType;\n /**\n * Indicates that the output speech is text marked up with SSML.\n */\n SSML: OutputSpeechType;\n};\n\n/**\n * Builds an OutputSpeech object that contains both text and ssml. The text is\n * convenient for showing information on cards, while building the ssml at the\n * same time.\n *\n * The OutputSpeech.type is always ssml.\n */\nexport class SpeechBuilder {\n private lc: string = `[${SpeechBuilder.name}]`;\n\n /**\n * The builder accumulates speech bits and then composes these together when\n * outputting.\n */\n private _bits: SpeechBit[];\n\n constructor() {\n const lc = `${this.lc}[ctor]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 38d63eb021d971a24d532aec75b60e22)`); }\n this._bits = [];\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Static factory function for fluent-style speech building.\n */\n static with(): SpeechBuilder { return new SpeechBuilder(); }\n\n /**\n * Adds a bit of speech corresponding to bare (non-ssml/tagged) text.\n *\n * @param text text to add to the builder\n */\n text(text: string): SpeechBuilder {\n let bit: SpeechBit = {\n type: \"text\",\n value: text + \"\"\n };\n this._bits.push(bit);\n return this;\n }\n /**\n * Adds a bit of speech corresponding to existing ssml.\n *\n * NOTE: This ssml should **NOT** contain a `<speak>` tag, as this\n * is not automatically stripped. Also, if you choose\n * `newParagraph`, ssml should **NOT** contain any hard-coded <p>\n * tags\n *\n * @param ssml ssml to add to the builder. See NOTE in function description.\n * @param newParagraph if true, wraps ssml in <p> tags. See NOTE in function description.\n */\n ssml(ssml: string, newParagraph: boolean = false): SpeechBuilder {\n const bit = {\n type: SpeechBitType.ssml,\n value: newParagraph ? `<p>${ssml}</p>` : ssml\n };\n this._bits.push(bit);\n return this;\n }\n /**\n * Adds a pause (<break> tag) in the speech builder.\n * Equivalent to `<break='${seconds}s'/>` ATOW.\n *\n * @param seconds amount of time to pause.\n */\n pause(seconds: number): SpeechBuilder {\n const bit = {\n type: SpeechBitType.break,\n value: seconds\n };\n this._bits.push(bit);\n return this;\n }\n\n /**\n * Syntactic sugar for adding text of '\\n'\n */\n newLine(): SpeechBuilder {\n const bit: SpeechBit = {\n type: 'text',\n value: '\\n'\n };\n this._bits.push(bit);\n return this;\n }\n\n /**\n * Syntactic sugar for adding text of '\\n\\n'\n */\n newParagraph(): SpeechBuilder {\n const bit: SpeechBit = {\n type: 'text',\n value: '\\n\\n'\n };\n this._bits.push(bit);\n return this;\n }\n\n /**\n * Takes text and/or ssml from existing `OutputSpeech`\n * object and adds it to the builder.\n *\n * For example, say you already have an outputSpeech and you just\n * want to add an intro text to it. You would create the builder,\n * add the intro text via `text` function and then call this\n * function with your existing outputSpeech.\n *\n * @example `let outputWithIntro = SpeechBuilder.with().text('Some intro text').existing(prevOutputSpeech).outputSpeech();`\n * @param outputSpeech existing `OutputSpeech` to weave into the builder.\n */\n existing(outputSpeech: OutputSpeech): SpeechBuilder {\n const bit: SpeechBit = {\n type: SpeechBitType.existingOutputSpeech,\n value: outputSpeech\n };\n this._bits.push(bit);\n return this;\n }\n /**\n * Creates an `OutputSpeech` from the builder's state.\n */\n outputSpeech({\n outputType = 'PlainText',\n }: {\n /**\n * Somewhat vestigial, originally for use with Alexa skills (I had\n * created ask-gib and this builder before Amazon's sdk was created.)\n */\n outputType?: OutputSpeechType,\n }): OutputSpeech {\n const lc = `${this.lc}[${this.outputSpeech.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3820fa4816d7ca999489b45fff5e2622)`); }\n\n outputType = outputType || 'PlainText';\n\n let text = \"\", ssml = \"\";\n if (logalot) { console.log(`${lc} about to do bits...`); }\n if (logalot) { console.log(`${lc} bits: ${JSON.stringify(this._bits)}`); }\n this._bits.forEach(bit => {\n if (logalot) { console.log(`${lc} ssml: ${ssml}`); }\n if (text || ssml) {\n text = text + \" \";\n ssml = ssml + \" \";\n }\n if (logalot) { console.log(`${lc} bit: ${JSON.stringify(bit)}`); }\n switch (bit.type) {\n case \"text\":\n if (logalot) { console.log(`${lc} text in case`); }\n text += bit.value;\n ssml += bit.value;\n break;\n case \"ssml\":\n if (logalot) { console.log(`${lc} ssml in case`); }\n // do these in two steps to fully strip ssml.\n text += bit.value;\n text = Ssml.stripSsml(text);\n ssml += bit.value;\n break;\n case \"break\":\n if (logalot) { console.log(`${lc} break in case`); }\n // ridic edge case, if pause before any text/ssml.\n if (ssml === \" \") { ssml = \"\"; }\n // text doesn't change\n ssml += `<break time='${bit.value}s'/>`;\n break;\n case \"existingOutputSpeech\":\n if (logalot) { console.log(`${lc} existing in case`); }\n const existing = bit.value as OutputSpeech;\n if (existing.text && existing.ssml) {\n if (logalot) { console.log(`${lc} existing text and ssml`); }\n text += existing.text;\n ssml += Ssml.unwrapSsmlSpeak(existing.ssml);\n } else if (existing.text) {\n if (logalot) { console.log(`${lc} existing text only`); }\n text += existing.text;\n ssml += text;\n } else if (existing.ssml) {\n if (logalot) { console.log(`${lc} existing ssml only`); }\n let unwrapped = Ssml.unwrapSsmlSpeak(existing.ssml);\n // do these in two steps to fully strip ssml.\n text += unwrapped;\n text = Ssml.stripSsml(text);\n ssml += unwrapped;\n } else { // neither existing ssml nor text?\n throw new Error(\"both existing.ssml and existing.text are falsy? (E: 089138a6ce8e45038028828515d9cd0c)\")\n }\n break;\n case \"phoneme\":\n throw new Error(\"phoneme case not implemented\");\n // break\n default:\n throw new Error(`Unknown bit.type: ${bit.type}`);\n }\n });\n if (logalot) {\n console.log(`${lc} text: ${JSON.stringify(text)}`);\n console.log(`${lc} ssml: ${JSON.stringify(ssml)}`);\n }\n const output: OutputSpeech = {\n type: outputType,\n text: text,\n ssml: Ssml.wrapSsmlSpeak([ssml], /*addParaTags*/ false)\n };\n // console.log(`${lc} output: ${JSON.stringify(output)}`);\n return output;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\nexport declare type SpeechBitType = \"text\" | \"ssml\" | \"break\" | \"phoneme\" | \"existingOutputSpeech\";\nexport declare const SpeechBitType: {\n text: SpeechBitType;\n ssml: SpeechBitType;\n break: SpeechBitType;\n phoneme: SpeechBitType;\n existingOutputSpeech: SpeechBitType;\n};\n/**\n * OutputSpeech objects are basically just arrays of these.\n */\nexport interface SpeechBit {\n type: SpeechBitType;\n value: string | number | OutputSpeech;\n}\n", "import { Lex, LexData, LexDatum, PropsData, } from '@ibgib/helper-gib/dist/helpers/lex-helper.mjs';\nimport { Ssml } from '@ibgib/helper-gib/dist/helpers/ssml-helper.mjs';\nimport { clone } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { Gib, IbGibAddr, TjpIbGibAddr, TransformResult } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport {\n WitnessData_V1, WitnessResultData, WitnessResultRel8ns, WitnessResultIbGib,\n} from '../witness-types.mjs';\nimport { CommentIbGib_V1 } from '../../common/comment/comment-types.mjs';\nimport { ROBBOT_TAG_TJP_ADDRS_REL8N_NAME } from './robbot-constants.mjs';\nimport { IbGibRobbotAny } from './robbot-base-v1.mjs';\nimport { WitnessWithContextData_V1, WitnessWithContextRel8ns_V1 } from '../witness-with-context/witness-with-context-types.mjs';\nimport { WitnessCmdData, WitnessCmdRel8ns, WitnessCmdIbGib, } from '../witness-cmd/witness-cmd-types.mjs';\n\n\nexport type RobbotTransparency = 'transparent' | 'translucent' | 'opaque';\n\nexport interface RobbotData_V1 extends WitnessWithContextData_V1 {\n\n /**\n * Name of a Robbot instance...after all, Robbie was only the first Robbot.\n */\n name: string;\n\n /**\n * Redeclared over {@link WitnessData_V1.uuid} making it a required field.\n */\n uuid: string;\n\n /**\n * For simpler robbots (i.e. early implementations), I'm not sure what this\n * will entail. Ideally the function dependency graph is public but right\n * now we're living with witness functionality \"off-chain\" (\"on-chain\"\n * stored in git version control).\n *\n * I think atm this will mean that any weighting will be public. If a robbot\n * has any randomness in its decision making, then this should be\n * translucent at least.\n *\n * Of course, even in the future when there are more sovereign \"A\"Is,\n * transparency doesn't mean you understand where he/she/it is coming from -\n * only that the raw data is available to see.\n */\n // reasoningTransparency: RobbotTransparency;\n\n /**\n * Transparency of timing of planned ibgibs to be presented to the user in a\n * context.\n *\n * For example, when the robbot is asked to process an ibgib context, it\n * must decide when to add which ibgibs to it's output context.\n */\n // schedulingTransparency: RobbotTransparency;\n\n /**\n * Minimum amount of time between outputs allowed by the robbot.\n */\n // minSecondsBetweenPosts: number;\n\n /**\n * Robbots work with scheduling and executing ibgib processing. But\n * it is often (always?) advantageous to give a certain amount of leeway\n * within the algorithms for making scheduling decisions. This is a\n * maximum time variance percentage per decision.\n *\n * So if there is a rigid schedule of every N days, then we allow that\n * it may indeed schedule the ibgib N +- (N * variance/100). If N is 50,\n * and max variance is 10, then this may schedule the output at\n * 50 plus or minus up to 5; consequently a range from 45-55.\n */\n // maxTimeVariancePercentage: number;\n\n /**\n * If true, then this robbot will be started upon app startup, and perhaps\n * in a background service in the future.\n *\n * if false, the robbot will schedule and execute a single \"round\" only when\n * prompted by a user.\n */\n // active: boolean;\n // for now, all robbot output will be passive, i.e., when you ask the robbot\n // within a context using the bottom action bar.\n\n /**\n * Some ibgibs work at the date (day) level of granularity, while others\n * work down to the time.\n */\n // scheduleGranularity: 'date' | 'time';\n\n /**\n * If provided, this will be prepended to any comments made by the robbot,\n * as well as the output subcontext if {@link outputMode} is\n * {@link RobbotOutputMode.subcontext}.\n */\n outputPrefix?: string;\n\n /**\n * If provided, this will be appended to any comments made by the robbot,\n * as well as the output subcontext if {@link outputMode} is\n * {@link RobbotOutputMode.subcontext}.\n */\n outputSuffix?: string;\n\n /**\n * There are multiple possibilities for where to output:\n *\n * 1. Inside the input context\n * 2. In a different subcontext ibgib\n * 3. In the robbot's ibgib (todo later)\n * 4. Tagged but not \"inside\" an ibgib (not planned atm).\n *\n * Also, it is possible to tag all outputs regardless of where the ibgibs\n * are placed originally. @see {@link tagOutput}\n *\n * ## thoughts\n *\n * Since the driving use case is to create drills, it would seem that inside\n * a single grouping ibgib within the output context makes the most sense.\n */\n // outputMode?: RobbotOutputMode;\n\n // /**\n // * If true, rel8s output context depending on {@link outputMode} to the latest\n // * tag(s) whose tjpAddr(s) are given in {@link RobbotRel8ns_V1}\n // * {@link ROBBOT_TAG_TJP_ADDRS_REL8N_NAME}.\n // */\n // tagOutput?: boolean;\n\n\n /**\n * When relating to an ibGib, this is the default rel8n name.\n *\n * @see `RobbotBase_V1.rel8To`\n */\n defaultRel8nName?: string;\n /**\n * list of all rel8n names, e.g. {@link defaultRel8nName},\n * that this robbot uses for \"my ibgibs\".\n */\n allRel8nNames?: string[];\n /**\n * escape sequence when requesting something from a robbot.\n *\n * So if a comment starts with this, then it's someone asking a robbot to do\n * something.\n */\n requestEscapeString?: string;\n\n}\n\n/**\n * default value for a robbot request escape string (that string to signify\n * a comment is a request of a robbot)\n */\nexport const DEFAULT_ROBBOT_REQUEST_ESCAPE_STRING = '?';\nexport const DEFAULT_ROBBOT_REQUEST_MAX_LENGTH = 100;\n\n\n// /**\n// * @see {@link RobbotData_V1.outputMode}\n// */\n// export type RobbotOutputMode = 'context' | 'subcontext' | 'ask';\n// export const RobbotOutputMode = {\n// /**\n// * spread out within the target context\n// */\n// context: 'context' as RobbotOutputMode,\n// /**\n// * creates a single comment ibgib and outputs within that\n// */\n// subcontext: 'subcontext' as RobbotOutputMode,\n// }\n// export const VALID_ROBBOT_OUTPUT_MODES = Object.values(RobbotOutputMode);\n\nexport interface RobbotRel8ns_V1 extends WitnessWithContextRel8ns_V1 {\n [ROBBOT_TAG_TJP_ADDRS_REL8N_NAME]?: TjpIbGibAddr[];\n}\n\n/**\n * A robbot's primary function when assigned to an ibgib is to analyze a context\n * ibgib as its input, and output ibgibs into the same or another context.\n *\n * This is quite similar to existing ideas of microservices, but with a few key\n * differences:\n *\n * 1. Robbots exist within the limited domain of ibgib transforms, i.e., `fork`,\n * `mut8` & `rel8` transforms.\n * 2. Robbots themselves live \"on-chain\" alongside the data with which they\n * interact.\n */\nexport interface RobbotIbGib_V1 extends IbGib_V1<RobbotData_V1, RobbotRel8ns_V1> {\n}\n\n\n\n/**\n * Cmds for interacting with ibgib spaces.\n *\n * Not all of these will be implemented for every space.\n *\n * ## todo\n *\n * change these commands to better structure, e.g., verb/do/mod, can/get/addrs\n * */\nexport type RobbotCmd =\n 'ib' | 'gib' | 'ibgib' | 'activate' | 'deactivate';\n/** Cmds for interacting with ibgib spaces. */\nexport const RobbotCmd = {\n /**\n * it's more like a grunt that is intepreted by context from the robbot.\n *\n * my initial use of this will be to add an ibgib to a robbot's\n * awareness. (input)\n */\n ib: 'ib' as RobbotCmd,\n /**\n * it's more like a grunt that is intepreted by context from the robbot.\n *\n * my initial use of this will be to indicate to a robbot to add to a\n * conversation. (output)\n */\n gib: 'gib' as RobbotCmd,\n /**\n * third placeholder command.\n *\n * I imagine this will be like \"what's up\", but who knows.\n */\n ibgib: 'ibgib' as RobbotCmd,\n /**\n * power on\n */\n activate: 'activate' as RobbotCmd,\n /** power off */\n deactivate: 'deactivate' as RobbotCmd,\n}\n\n/**\n * Flags to affect the command's interpretation.\n */\nexport type RobbotCmdModifier =\n 'ib' | 'gib' | 'ibgib';\n/**\n * Flags to affect the command's interpretation.\n */\nexport const RobbotCmdModifier = {\n /**\n * hmm...\n */\n ib: 'ib' as RobbotCmdModifier,\n /**\n * hmm...\n */\n gib: 'gib' as RobbotCmdModifier,\n /**\n * hmm...\n */\n ibgib: 'ibgib' as RobbotCmdModifier,\n}\n\n/** Information for interacting with spaces. */\nexport interface RobbotCmdData\n extends WitnessCmdData<RobbotCmd, RobbotCmdModifier> {\n}\n\nexport interface RobbotCmdRel8ns extends WitnessCmdRel8ns {\n}\n\n/**\n * Shape of options ibgib if used for a robbot.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface RobbotCmdIbGib<\n TIbGib extends IbGib_V1 = IbGib_V1,\n TCmdData extends RobbotCmdData = RobbotCmdData,\n TCmdRel8ns extends RobbotCmdRel8ns = RobbotCmdRel8ns,\n> extends WitnessCmdIbGib<TIbGib, RobbotCmd, RobbotCmdModifier, TCmdData, TCmdRel8ns> {\n}\n\n/**\n * Optional shape of result data to robbot interactions.\n *\n * This is in addition of course to {@link WitnessResultData}.\n *\n * ## notes\n *\n * * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface RobbotResultData extends WitnessResultData {\n}\n\n/**\n * Marker interface rel8ns atm...\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface RobbotResultRel8ns extends WitnessResultRel8ns { }\n\n/**\n * Shape of result ibgib if used for a robbot.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface RobbotResultIbGib<\n TIbGib extends IbGib_V1,\n TResultData extends RobbotResultData,\n TResultRel8ns extends RobbotResultRel8ns\n>\n extends WitnessResultIbGib<TIbGib, TResultData, TResultRel8ns> {\n}\n\n/**\n * When a robbot creates a comment on a context ibgib, he/she also relates it to\n * itself via this rel8nName.\n *\n * @example robbot.rel8ns.my_comment = 'comment myawesomeopinion wordyrobbot123^ABC'\n *\n * ## notes\n *\n * * \"my\" prefix is used to differentiate between the robbot's comments and comments\n * on the robbot itself.\n */\nexport const ROBBOT_MY_COMMENTS_REL8N_NAME = 'my_comment';\n/**\n * When a robbot participates in a conversation, that context is related via\n * this rel8n name.\n * @example robbot.rel8ns.context = 'comment someconvo^ABC'\n */\nexport const ROBBOT_CONTEXT_REL8N_NAME = 'context';\n/**\n * Used to rel8 session ibgibs to robbots.\n * @example robbot.rel8ns.session = ['session 123^ABC'];\n */\nexport const ROBBOT_SESSION_REL8N_NAME = 'session';\n/**\n * Used to rel8 interaction to sessions,\n * @example session.rel8ns.interaction = ['interaction 123^ABC'];\n */\nexport const ROBBOT_INTERACTION_REL8N_NAME = 'interaction';\n\nexport const ROBBOT_ATOM = \"robbot\";\nexport const ROBBOT_SESSION_ATOM = 'robbot_session';\nexport const ROBBOT_ANALYSIS_ATOM = 'robbot_analysis';\nexport const ROBBOT_INTERACTION_ATOM = 'robbot_interaction';\n\n\n/**\n * This is stimulus that is coming over the Context that a robbot is being\n * stimulated with.\n *\n * This is different than stimulus that the robbot provides for a given ibgib.\n */\nexport interface StimulusForRobbot {\n /**\n * The actual ibgib that is the stimulus.\n *\n * If falsy, `isClick` should be true.\n */\n ibGib?: IbGib_V1;\n /**\n * should be true if the user has typed in a request and added the\n * comment to the context.\n */\n isRequest?: boolean;\n /**\n * The stimulus was generated from a click on a button, as opposed to a\n * comment typed in or a picture/link/comment added/imported in a context.\n *\n * Should be true if `ibGib` is falsy.\n */\n isClick?: boolean;\n}\n\nexport type RobbotInteractionType = 'greeting' | 'stimulation' | 'farewell' | 'info' | 'help';\nexport const RobbotInteractionType = {\n /**\n * opening statement of a robbot\n */\n greeting: 'greeting' as RobbotInteractionType,\n /**\n * stimulates a certain ibgib.\n */\n stimulation: 'stimulation' as RobbotInteractionType,\n /**\n * closing statements of a robbot\n */\n farewell: 'farewell' as RobbotInteractionType,\n /**\n * small nudges of info, including possibly repeating previous statement.\n */\n info: 'info' as RobbotInteractionType,\n /**\n * providing info about context to aid the user in their options.\n */\n help: 'help' as RobbotInteractionType,\n}\n\n\nexport const DEFAULT_INTERACTION_SUBJECTTJPGIBS_DELIM = '_';\nexport const UNDEFINED_INTERACTION_SUBJECTTJPGIBS_STRING = 'undefined';\n\nexport interface RobbotInteractionIbInfo {\n atom: string,\n type: string,\n timestampInTicks: string,\n subjectTjpGibs?: Gib[],\n addlDetailsText?: string,\n}\n\nexport interface RobbotInteractionData_V1 extends IbGibData_V1 {\n timestamp: string;\n /**\n * type of this interaction. for now, this is strongly typed, but\n * later I should add a catchall `| string` type to allow for\n * expansion.\n */\n type: RobbotInteractionType;\n /**\n * The tjpGib of the interaction's context ibgib.\n */\n contextTjpGib: Gib;\n /**\n * When an interaction pertains to particular timelines, e.g. stimulating\n * one or more ibgibs, those tjp gibs should be listed here.\n */\n subjectTjpGibs?: Gib[];\n /**\n * Produced comment text from the interaction. This should be the\n * content of text that the robbot outputs to the context.\n */\n commentText?: string;\n /**\n * should be an interfaced data object that represents the details of the\n * interaction, e.g. if a stimulation, then here is the simulation interface data.\n *\n * ## notes\n *\n * to create another generic interface here would be too unwieldy. (already may be!)\n */\n details?: any;\n /**\n * If interaction is associated with a session, here is the session tjp addr.\n */\n '@sessionTjp'?: TjpIbGibAddr;\n /**\n * If interaction is associated with a session, here is the session id.\n */\n sessionId?: string;\n /**\n * Flag to indicate if the interaction is expecting a response, like a\n * question to be answered by the user.\n */\n expectingResponse?: boolean;\n}\nexport interface RobbotInteractionRel8ns_V1 extends IbGibRel8ns_V1 {\n}\nexport interface RobbotInteractionIbGib_V1\n extends IbGib_V1<RobbotInteractionData_V1, RobbotInteractionRel8ns_V1> { }\n\nexport interface RobbotSessionData_V1 extends IbGibData_V1 {\n timestamp: string;\n /**\n * Soft link to the context address where the session takes place.\n */\n '@context': IbGibAddr;\n /**\n * Soft link to the context's tjp address where the session takes place.\n */\n '@contextTjp': IbGibAddr;\n}\nexport interface RobbotSessionRel8ns_V1 extends IbGibRel8ns_V1 {\n interaction?: IbGibAddr[];\n}\nexport interface RobbotSessionIbGib_V1 extends IbGib_V1<RobbotSessionData_V1, RobbotSessionRel8ns_V1> { }\n\n\n/**\n * These are used for raw words/phrases that compose larger, more complex\n * semantic ideas that use SemanticId.\n *\n * Because these are used in composition of lex data, they are not prefixed\n * with something like \"atomic_\", e.g. \"atomic_hi\".\n */\nexport type AtomicId =\n 'hi' | 'welcome' | 'bye' |\n 'yes' | 'no' |\n 'learn' |\n 'wtg';\nexport const AtomicId = {\n hi: 'hi' as AtomicId,\n welcome: 'welcome' as AtomicId,\n bye: 'bye' as AtomicId,\n yes: 'yes' as AtomicId,\n no: 'no' as AtomicId,\n learn: 'learn' as AtomicId,\n wtg: 'wtg' as AtomicId,\n}\n\n/**\n * These are used for specific lex commands/intents/whatevers. Synonyms and\n * equivalency phrases ultimately get resolved to these.\n *\n * These are complex concepts, as opposed to the smaller atomic words/phrases, that\n * a robbot will use when interacting with users.\n *\n * ## example\n *\n * A robbot may say in a semantic greeting (SemanticId.hello) that incorporates\n * a lot of context-specific text. However, these individual greetings will\n * most likely include the usage of individual phrases like 'hi' or 'good day'.\n * These are small, raw \"atomic\" lexical atoms.\n */\nexport type SemanticId =\n 'semantic_help' |\n 'semantic_hello' | 'semantic_bye' |\n 'semantic_yes' | 'semantic_no' | 'semantic_cancel' |\n 'semantic_skip' | 'semantic_forget' | 'semantic_next' |\n 'semantic_please' |\n 'semantic_in_progress' |\n 'semantic_list' |\n 'semantic_request' |\n 'semantic_count' |\n 'semantic_options' |\n 'semantic_ready' |\n 'semantic_stop' |\n 'semantic_result' |\n 'semantic_unknown' | 'semantic_default' |\n string; // have to do this for inheritance?\n/**\n * enum constant for use with {@link SemanticInfo}.\n */\nexport const SemanticId = {\n help: 'semantic_help' as SemanticId,\n hello: 'semantic_hello' as SemanticId,\n bye: 'semantic_bye' as SemanticId,\n yes: 'semantic_yes' as SemanticId,\n no: 'semantic_no' as SemanticId,\n cancel: 'semantic_cancel' as SemanticId,\n skip: 'semantic_skip' as SemanticId,\n forget: 'semantic_forget' as SemanticId,\n next: 'semantic_next' as SemanticId,\n please: 'semantic_please' as SemanticId,\n in_progress: 'semantic_in_progress' as SemanticId,\n list: 'semantic_list' as SemanticId,\n request: 'semantic_request' as SemanticId,\n count: 'semantic_count' as SemanticId,\n options: 'semantic_options' as SemanticId,\n ready: 'semantic_ready' as SemanticId,\n stop: 'semantic_stop' as SemanticId,\n result: 'semantic_result' as SemanticId,\n unknown: 'semantic_unknown' as SemanticId,\n default: 'semantic_default' as SemanticId,\n};\n\n/**\n * Info related to a semantic interpretation of one user (or ai/other) when\n * communicating to another witness.\n */\nexport interface SemanticInfo {\n /**\n * Id if already determined by runtime code.\n */\n semanticId?: SemanticId;\n /**\n * request (comment) ibgib if the semantic meaning maps to a request.\n */\n request?: CommentIbGib_V1;\n /**\n * placeholder per use case of another ibgib.\n */\n other?: IbGib_V1;\n /**\n * true if the semantic meaning is deemed a continuation of a previous\n * semantic statement.\n */\n isContinuation?: boolean;\n}\n\nexport interface SemanticHandlerResult {\n interaction: RobbotInteractionIbGib_V1 | null;\n /**\n * Should be set to true if the interaction is aborted (i.e. we're ignoring\n * some stimulus). Like if we're expecting a response, but some other ibgib\n * is given (maybe some users/other robbots are talking and it doesn't\n * pertain to us).\n */\n ignored?: boolean;\n /**\n * If the handler is expecting a response (however the handler may interpret that response),\n *\n */\n // responseSubject?: ReplaySubject<IbGib_V1 | null>;\n // onResponse?: (response: IbGib_V1|null) => Promise<void>;\n}\nexport interface SemanticHandler {\n /**\n * This should be a unique id for this handler.\n */\n handlerId: string;\n /**\n * The semanticId that this handler is associated with.\n */\n semanticId: SemanticId;\n /**\n * If truthy, the robbot should execute this filter before\n * attempting to execute this handler's {@link fnExec}\n */\n fnCanExec: (info: SemanticInfo) => Promise<boolean>;\n /**\n * Actual function of handler that gets executed if context is\n * correct ({@link fnCanHandle} is true).\n */\n fnExec: (info: SemanticInfo) => Promise<SemanticHandlerResult>;\n /**\n * If the user cancels the response and this is truthy, this is called.\n */\n fnCancelResponse?: () => Promise<void>;\n // handleSubject$: ReplaySubject<SemanticInfo>;\n // handleResult$: ReplaySubject<SemanticHandlerResult>;\n}\n\nexport interface RobbotPropsData<TSemanticId extends SemanticId = SemanticId> extends PropsData {\n /**\n * This datum expects these template vars.\n *\n * This is not strictly necessary, but is used for documentation/aid to the\n * caller on providing stuff for the datum for what is expected.\n */\n templateVars?: string;\n /**\n * If assigned, then this lex datum is a semantic entry, and this is the corresponding\n * semantic id.\n */\n semanticId?: TSemanticId;\n atomicId?: AtomicId;\n /**\n * Only use this lex datum if YES there is an active session in progress.\n */\n onlyInSession?: boolean;\n /**\n * Only use this lex datum if there is NOT an active session in progress.\n */\n onlyNotInSession?: boolean;\n /**\n * The robbot hasn't seen anything so has no knowledge/has nothing to work\n * on.\n */\n blankSlate?: boolean;\n /**\n * Just starting a new session, i.e. no prev interactions exist.\n */\n freshStart?: boolean;\n /**\n * Flag to indicate if the lex datum corresponds to a user request.\n */\n isRequest?: boolean;\n}\n\nexport function toLexDatums_Semantics(semanticId: SemanticId, texts: string[]): LexDatum<RobbotPropsData>[] {\n return texts.flatMap(t => {\n return {\n texts: [t],\n language: 'en-US',\n props: { semanticId },\n } as LexDatum<RobbotPropsData>;\n });\n}\nexport function toLexDatums_Atomics(atomicId: AtomicId, texts: string[]): LexDatum<RobbotPropsData>[] {\n return texts.flatMap(t => {\n return {\n texts: [t],\n language: 'en-US',\n props: { atomicId },\n } as LexDatum<RobbotPropsData>;\n });\n}\n\nexport const DEFAULT_HUMAN_LEX_DATA_ENGLISH_SEMANTICS: LexData<RobbotPropsData> = {\n [SemanticId.help]: [\n ...toLexDatums_Semantics(SemanticId.help, [\n 'h', 'help', 'help me',\n ]),\n ],\n [SemanticId.yes]: [\n ...toLexDatums_Semantics(SemanticId.yes, [\n 'yes', 'y', 'yeah', 'yea', 'aye', 'yup', 'yep', 'sure', 'ok',\n 'sounds good', 'go for it', 'yes please', 'yes thanks', 'ok thanks',\n 'uh huh', 'god yes', 'affirmative', 'ten four', '10-4', 'roger',\n ]),\n ],\n [SemanticId.no]: [\n ...toLexDatums_Semantics(SemanticId.no, [\n 'no', 'n', 'nah', 'nay', 'nope', 'uh uh', 'no thanks', 'ick', 'nuh uh',\n 'god no', 'no way', 'not at all', 'negative', 'that\\'s a negative', 'nein',\n ])\n ],\n [SemanticId.cancel]: [\n ...toLexDatums_Semantics(SemanticId.cancel, [\n 'cancel', 'nm', 'nevermind', 'cancel that', 'don\\'t worry about it'\n ])\n ],\n [SemanticId.skip]: [\n ...toLexDatums_Semantics(SemanticId.skip, [\n 'skip', 'sk',\n ])\n ],\n [SemanticId.forget]: [\n ...toLexDatums_Semantics(SemanticId.forget, [\n 'forget', 'forget this', 'forget this one',\n ])\n ],\n [SemanticId.next]: [\n ...toLexDatums_Semantics(SemanticId.next, [\n 'next', // 'next $(please)' /* need to get this kind of thing working */\n ])\n ],\n [SemanticId.bye]: [\n ...toLexDatums_Semantics(SemanticId.bye, [\n 'bye', 'bye bye', 'see you later', 'see you',\n ])\n ],\n [SemanticId.unknown]: [\n ...toLexDatums_Semantics(SemanticId.unknown, [\n 'are you mocking me, human?', 'mmhmm...', 'i see...', 'does not compute...', 'indeed'\n ])\n ],\n};\nexport const DEFAULT_HUMAN_LEX_DATA_ENGLISH_ATOMICS: LexData<RobbotPropsData> = {\n [AtomicId.hi]: [\n ...toLexDatums_Atomics(AtomicId.hi, [\n 'hi', 'howdy', 'hello', 'greetings', 'good day', 'hello there', 'good day to you', 'yo',\n ]),\n ],\n [AtomicId.welcome]: [\n ...toLexDatums_Atomics(AtomicId.welcome, [\n 'welcome',\n ]),\n ],\n [AtomicId.yes]: [\n ...toLexDatums_Atomics(AtomicId.yes, [\n 'yes', 'y', 'yeah', 'yea', 'aye', 'yup', 'yep', 'sure', 'ok',\n 'sounds good', 'go for it', 'yes please', 'yes thanks', 'ok thanks',\n 'uh huh', 'god yes', 'affirmative', 'ten four', '10-4', 'roger',\n ]),\n ],\n [AtomicId.no]: [\n ...toLexDatums_Atomics(AtomicId.no, [\n 'no', 'n', 'nope', 'no thanks', 'no thank you',\n ]),\n ],\n [AtomicId.bye]: [\n ...toLexDatums_Atomics(AtomicId.bye, [\n 'bye', 'bye bye', 'adios', 'ciao', 'later',\n ]),\n ],\n [AtomicId.learn]: [\n ...toLexDatums_Atomics(AtomicId.learn, [\n 'learn', 'study', 'review',\n ]),\n ],\n [AtomicId.wtg]: [\n ...toLexDatums_Atomics(AtomicId.wtg, [\n 'wtg', 'nice', 'not bad', 'pretty good', 'good job',\n ]),\n ],\n}\nexport const DEFAULT_HUMAN_LEX_DATA_ENGLISH: LexData<RobbotPropsData> = {\n ...DEFAULT_HUMAN_LEX_DATA_ENGLISH_SEMANTICS,\n ...DEFAULT_HUMAN_LEX_DATA_ENGLISH_ATOMICS,\n}\nexport const DEFAULT_HUMAN_LEX_DATA: LexData<RobbotPropsData> = {\n ...clone(DEFAULT_HUMAN_LEX_DATA_ENGLISH),\n};\n\nexport const DEFAULT_USER_LEX_DATA: LexData<RobbotPropsData> = {\n ...clone(DEFAULT_HUMAN_LEX_DATA),\n}\n\n/**\n * This lex is to be used for parsing user responses.\n *\n * Also, you can use this in the robbot's responses, if you initialize the\n * robbot's lex to include this. This way, the robbot speaks as he/she expects\n * to be spoken to.\n *\n * So when a user says 'yes', we can interpret it via a lookup in the lex data.\n * we will find the id filter via keywords.\n */\nexport const DEFAULT_USER_LEX = new Lex<RobbotPropsData>(DEFAULT_USER_LEX_DATA, {\n requestLanguage: \"en-US\", defaultLanguage: \"en-US\",\n defaultCapitalize: \"none\",\n defaultLineConcat: \"delim\", defaultDelim: \"\\n\\n\",\n defaultKeywordMode: \"any\", defaultPropsMode: \"prop\",\n});\n\n/**\n * default phrases for the robbot to use when chatting.\n */\nexport const DEFAULT_ROBBOT_LEX_DATA: LexData<RobbotPropsData> = {\n ...clone(DEFAULT_HUMAN_LEX_DATA),\n};\n// adjust for robbot-ness a bit\nDEFAULT_ROBBOT_LEX_DATA[SemanticId.bye].push(\n {\n texts: ['EOL',],\n ssmls: [Ssml.sub('EOL', 'end of line'),],\n language: 'en-US',\n props: { semanticId: SemanticId.bye, },\n weighting: 100,\n }\n)\nDEFAULT_ROBBOT_LEX_DATA[SemanticId.unknown] = [\n ...toLexDatums_Semantics(SemanticId.unknown, [\n 'i\\'m not quite sure what you mean', 'does not compute',\n ])\n];\n\nexport type RobbotPromptResult = TransformResult<IbGibRobbotAny>;\n", "import { delay, getSaferSubstring, getTimestampInTicks, getUUID, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { Gib, Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { validateGib, validateIb, validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { GIB, IbGib_V1, getGib, getGibInfo, } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\n\nimport { IbGibTimelineUpdateInfo } from '../../common/other/other-types.mjs';\nimport { WitnessFormBuilder } from '../witness-form-builder.mjs';\nimport { IbGibRobbotAny } from './robbot-base-v1.mjs';\nimport {\n DEFAULT_INTERACTION_SUBJECTTJPGIBS_DELIM,\n UNDEFINED_INTERACTION_SUBJECTTJPGIBS_STRING,\n DEFAULT_ROBBOT_REQUEST_ESCAPE_STRING,\n RobbotData_V1, RobbotIbGib_V1, RobbotInteractionData_V1, RobbotInteractionIbGib_V1,\n RobbotInteractionIbInfo, RobbotInteractionRel8ns_V1, RobbotInteractionType,\n ROBBOT_INTERACTION_ATOM, ROBBOT_SESSION_ATOM, DEFAULT_ROBBOT_REQUEST_MAX_LENGTH, RobbotPromptResult,\n} from './robbot-types.mjs';\nimport { IbGibSpaceAny } from '../space/space-base-v1.mjs';\nimport { persistTransformResult, registerNewIbGib, rel8ToSpecialIbGib } from '../space/space-helper.mjs';\nimport { isComment, parseCommentIb } from '../../common/comment/comment-helper.mjs';\nimport { ROBBOT_REL8N_NAME } from './robbot-constants.mjs';\nimport { GLOBAL_LOG_A_LOT, ROBBOT_NAME_REGEXP, ROBBOT_PREFIX_SUFFIX_REGEXP, ROBBOT_PREFIX_SUFFIX_REGEXP_DESC } from '../../core-constants.mjs';\nimport { MetaspaceService } from '../space/metaspace/metaspace-types.mjs';\nimport { UUID_REGEXP } from '@ibgib/helper-gib/dist/constants.mjs';\n\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n\nexport function getRobbotResultMetadata({ robbot }: { robbot: IbGibRobbotAny }): string {\n return `${robbot.ib} ${getTimestampInTicks()}`;\n}\n\n\nexport function validateCommonRobbotData({\n robbotData,\n}: {\n robbotData?: RobbotData_V1,\n}): string[] {\n const lc = `[${validateCommonRobbotData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!robbotData) { throw new Error(`robbotData required (E: 1ac78ffae5354b67acb64a34cfe23c2f)`); }\n const errors: string[] = [];\n const {\n name, uuid, classname,\n outputPrefix, outputSuffix,\n } =\n robbotData;\n\n if (name) {\n if (!name.match(ROBBOT_NAME_REGEXP)) {\n errors.push(`name must match regexp: ${ROBBOT_NAME_REGEXP}`);\n }\n } else {\n errors.push(`name required.`);\n }\n\n if (uuid) {\n if (!uuid.match(UUID_REGEXP)) {\n errors.push(`uuid must match regexp: ${UUID_REGEXP}`);\n }\n } else {\n errors.push(`uuid required.`);\n }\n\n if (outputPrefix) {\n if (!outputPrefix.match(ROBBOT_PREFIX_SUFFIX_REGEXP)) {\n errors.push(`outputPrefix must match regexp: ${ROBBOT_PREFIX_SUFFIX_REGEXP}`);\n }\n }\n\n if (outputSuffix) {\n if (!outputSuffix.match(ROBBOT_PREFIX_SUFFIX_REGEXP)) {\n errors.push(`outputSuffix must match regexp: ${ROBBOT_PREFIX_SUFFIX_REGEXP}`);\n }\n }\n\n if (classname) {\n if (!classname.match(ROBBOT_NAME_REGEXP)) {\n errors.push(`classname must match regexp: ${ROBBOT_NAME_REGEXP}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateCommonRobbotIbGib({\n robbotIbGib,\n}: {\n robbotIbGib: RobbotIbGib_V1,\n}): Promise<string[] | undefined> {\n const lc = `[${validateCommonRobbotIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f7b34d791a483b8c5a9d188da66d3f22)`); }\n const intrinsicErrors: string[] = await validateIbGibIntrinsically({ ibGib: robbotIbGib }) ?? [];\n\n if (!robbotIbGib.data) { throw new Error(`robbotIbGib.data required (E: 754a8d2540610696aff04b0d159daa23)`); }\n const ibErrors: string[] = [];\n let { robbotClassname, robbotName, robbotId } = parseRobbotIb({ robbotIb: robbotIbGib.ib });\n if (!robbotClassname) { ibErrors.push(`robbotClassname required (E: 3234d39bf1c74ec3aff59f374282dfc8)`); }\n if (!robbotName) { ibErrors.push(`robbotName required (E: b329dcc62ff548d7aa0681393b2c7057)`); }\n if (!robbotId) { ibErrors.push(`robbotId required (E: b562c953bfaf4dd49e4d3a08304ee2fc)`); }\n\n const dataErrors = validateCommonRobbotData({ robbotData: robbotIbGib.data });\n\n let result = [...(intrinsicErrors ?? []), ...(ibErrors ?? []), ...(dataErrors ?? [])];\n if (result.length > 0) {\n return result;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getRobbotIb({\n robbotData,\n classname,\n}: {\n robbotData: RobbotData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getRobbotIb.name}]`;\n try {\n const validationErrors = validateCommonRobbotData({ robbotData });\n if (validationErrors.length > 0) { throw new Error(`invalid robbotData: ${validationErrors} (E: 390316b7c4fb0bd104ddc4e6c2e12922)`); }\n if (classname) {\n if (robbotData.classname && robbotData.classname !== classname) { throw new Error(`classname does not match robbotData.classname (E: e21dbc830856fbcee1d3ab260b0c5922)`); }\n } else {\n classname = robbotData.classname;\n if (!classname) { throw new Error(`classname required (E: e0519f89df8a468c8743cb932f436bfe)`); }\n }\n\n // ad hoc validation here. should centralize witness classname validation\n\n const { name, uuid } = robbotData;\n return `witness robbot ${classname} ${name} ${uuid}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Current schema is `witness robbot [classname] [robbotName] [robbotId]\n *\n * NOTE this is space-delimited\n */\nexport function parseRobbotIb({\n robbotIb,\n}: {\n robbotIb: Ib,\n}): {\n robbotClassname: string,\n robbotName: string,\n robbotId: string,\n} {\n const lc = `[${parseRobbotIb.name}]`;\n try {\n if (!robbotIb) { throw new Error(`robbotIb required (E: 4a35881058094f1a90bb4ea37052d6d7)`); }\n\n const pieces = robbotIb.split(' ');\n\n return {\n robbotClassname: pieces[2],\n robbotName: pieces[3],\n robbotId: pieces[4],\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n\n/**\n * Prompts the user a form to build the robbot.\n *\n * Once prompted, the robbot is:\n * 1. validated\n * 2. persisted in the given {@link space}\n * 3. registered with the space\n * 4. related to the space's special robbots index\n * 5. new robbot is returned\n *\n * @returns newly created robbot ibgib (witness)\n */\nexport async function createNewRobbot({\n fnPromptRobbot,\n ibgibs,\n space,\n}: {\n fnPromptRobbot: (space: IbGibSpaceAny, ibGib: RobbotIbGib_V1 | null) => Promise<RobbotPromptResult | undefined>;\n /**\n * Either {@link common} or {@link ibgibs} is required\n * @hack\n */\n ibgibs?: MetaspaceService,\n /**\n * space within which to create the robbot. if not provided, the\n * defaults to the local user space via {@link common} or {@link ibgibs}.\n */\n space: IbGibSpaceAny,\n}): Promise<IbGibRobbotAny | undefined> {\n const lc = `[${createNewRobbot.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!ibgibs) { throw new Error(`(UNEXPECTED) ibgibs service required. (E: 4be5d20dc81fcdabb8d7d4cd47458522)`); }\n\n space = space ?? await ibgibs.getLocalUserSpace({ lock: true });\n\n // prompt user to create the ibgib, passing in null because we're\n // creating not editing.\n let resRobbot = await fnPromptRobbot(space, /*ibGib because creating*/null);\n\n if (!resRobbot) { throw new Error(`robbot prompt returned nothing. canceled? (E: 1a08529b53bd3d79c6587b196e5e0823)`); }\n\n /** this should be the witness class itself at this point. */\n const newRobbot = (resRobbot.newIbGib as IbGibRobbotAny);\n // let loading = await common.loadingCtrl.create({ message: 'creating...' });\n try {\n // await loading.present();\n await delay(1000); // ensure that the user sees a creating message\n let allIbGibs: IbGib_V1[] = [];\n allIbGibs.push(newRobbot);\n resRobbot.intermediateIbGibs?.forEach(x => allIbGibs.push(x));\n resRobbot.dnas?.forEach(x => allIbGibs.push(x));\n for (let i = 0; i < allIbGibs.length; i++) {\n const ibGib = allIbGibs[i];\n const validationErrors = await validateIbGibIntrinsically({ ibGib });\n if ((validationErrors ?? []).length > 0) { throw new Error(`(unexpected) invalid robbot ibgib created. validationErrors: ${validationErrors}. robbot: ${pretty(newRobbot.toIbGibDto())} (E: a683268621cd6dd3dd60310b164c4d22)`); }\n }\n\n await persistTransformResult({ resTransform: resRobbot, space });\n const { zeroSpace, fnBroadcast, fnUpdateBootstrap } = ibgibs;\n await registerNewIbGib({\n ibGib: newRobbot,\n space,\n fnBroadcast: (x: IbGibTimelineUpdateInfo) => fnBroadcast(x),\n });\n\n await rel8ToSpecialIbGib({\n type: \"robbots\",\n rel8nName: ROBBOT_REL8N_NAME,\n ibGibsToRel8: [newRobbot],\n space,\n zeroSpace,\n fnUpdateBootstrap,\n fnBroadcast,\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n // } finally {\n // await loading.dismiss();\n }\n return newRobbot;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport class RobbotFormBuilder extends WitnessFormBuilder {\n protected lc: string = `[${RobbotFormBuilder.name}]`;\n\n constructor() {\n super();\n this.what = 'robbot';\n }\n\n outputPrefix({\n of,\n required,\n defaultValue,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n }): RobbotFormBuilder {\n this.addItem({\n // witness.data.outputPrefix\n name: \"outputPrefix\",\n description: `Technical setting that sets a prefix for all text output of the robbot.`,\n label: \"Output Prefix\",\n regexp: ROBBOT_PREFIX_SUFFIX_REGEXP,\n regexpErrorMsg: ROBBOT_PREFIX_SUFFIX_REGEXP_DESC,\n dataType: 'textarea',\n value: of,\n defaultValue,\n required,\n });\n return this;\n }\n\n outputSuffix({\n of,\n required,\n defaultValue,\n }: {\n of: string,\n required?: boolean,\n defaultValue?: string,\n }): RobbotFormBuilder {\n this.addItem({\n // witness.data.outputSuffix\n name: \"outputSuffix\",\n description: `Technical setting that sets a suffix for all text output of the ${this.what}. (like a signature)`,\n label: \"Output Suffix\",\n regexp: ROBBOT_PREFIX_SUFFIX_REGEXP,\n regexpErrorMsg: ROBBOT_PREFIX_SUFFIX_REGEXP_DESC,\n dataType: 'textarea',\n value: of,\n defaultValue,\n required,\n });\n return this;\n }\n\n}\n\n/**\n * checks to see if the comment is an ibgib and if that comment starts\n * with the escape sequence.\n */\nexport function isRequestComment({\n ibGib,\n requestEscapeString = DEFAULT_ROBBOT_REQUEST_ESCAPE_STRING,\n}: {\n ibGib: IbGib_V1,\n requestEscapeString?: string,\n}): boolean {\n const lc = `${isRequestComment.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d7c49619ffb7a9c26d9d74959b91ae22)`); }\n\n if (!isComment({ ibGib })) { return false; /* <<<< returns early */ }\n\n let { ib } = ibGib;\n if (!ib) { throw new Error(`ib or ibGib.ib required (E: d92c26b15fc143977955a167b8b67522)`); }\n\n requestEscapeString = requestEscapeString || DEFAULT_ROBBOT_REQUEST_ESCAPE_STRING;\n\n let { safeIbCommentText } = parseCommentIb({ ib });\n\n return safeIbCommentText.startsWith(requestEscapeString);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Strips the request escape string and any non-alphanumeric characters except spaces,\n * returning the rest fo the string up to `maxLength`.\n *\n * This does *not* interpret anything beyond this.\n */\nexport function getSpaceDelimitedSaferRequestText({\n ibGib,\n requestEscapeString = DEFAULT_ROBBOT_REQUEST_ESCAPE_STRING,\n lowercase,\n maxLength,\n}: {\n ibGib: IbGib_V1,\n requestEscapeString?: string,\n lowercase?: boolean,\n maxLength?: number,\n}): string {\n const lc = `${getSpaceDelimitedSaferRequestText.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b4cbe054fe254414b77204ad80e519aa)`); }\n\n if (!isComment({ ibGib })) { throw new Error(`ibGib is not a comment (E: ab34df44eb57c170cec6c6db6f4f5722)`); }\n\n let { data } = ibGib;\n if (!data) { throw new Error(`ibGib.data required (E: 6155a49a0c1286c0bb8aa6f81c396522)`); }\n\n let text: string = data.text;\n\n requestEscapeString = requestEscapeString || DEFAULT_ROBBOT_REQUEST_ESCAPE_STRING;\n const length = maxLength || DEFAULT_ROBBOT_REQUEST_MAX_LENGTH;\n\n text = getSaferSubstring({\n text: text,\n length,\n keepLiterals: [' ', requestEscapeString]\n });\n\n text = text\n .substring(requestEscapeString.length) // remove the escape string\n .trim();\n\n if (lowercase) {\n text = text.toLowerCase();\n }\n\n return text;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Creates space-delimited ib. Extracts certain info from `data` and appends\n * addlDetailsText at the end.\n *\n * atow the schema is:\n *\n * return addlDetailsText ?\n * `${ROBBOT_INTERACTION_ATOM} ${data.type} ${timestampInTicks} ${subjectTjpGibsString} ${addlDetailsText}` :\n * `${ROBBOT_INTERACTION_ATOM} ${data.type} ${timestampInTicks} ${subjectTjpGibsString}`;\n *\n * @returns space-delimited interaction ib\n */\nexport function getInteractionIb({\n data,\n addlDetailsText,\n}: {\n data: RobbotInteractionData_V1,\n addlDetailsText?: string,\n}): Ib {\n const lc = `[${getInteractionIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 9ac657cab7e292e2bd587595757ab622)`); }\n if (!data) { throw new Error(`data required (E: 8fac6ce2ae6dd521255dc8ba241a5222)`); }\n if (!data.type) { throw new Error(`data.type required (E: 77786fe653be04c9fa33e30ac3b77f22)`); }\n let saferType = getSaferSubstring({ text: data.type, length: 32 });\n if (data.type !== saferType) { throw new Error(`invalid data.type (${data.type}). Should be safer like (${saferType}) (E: efe7888da08f148c8972c0923356b122)`); }\n\n if (!data.timestamp) { throw new Error(`data.timestamp required (E: 8682a5af1cd48d0cb372b7f519a61e22)`); }\n const dataTimestampIsInt = Number.isInteger(Number.parseInt(data.timestamp));\n const timestampInTicks = dataTimestampIsInt ?\n data.timestamp :\n getTimestampInTicks(data.timestamp);\n\n const subjectTjpGibs = data.subjectTjpGibs ?? [];\n let subjectTjpGibsString: string;\n if (subjectTjpGibs.length === 0) {\n if (logalot) { console.log(`${lc} data.subjectTjpGibs is falsy. defaulting subjectTjpGibsString to ${UNDEFINED_INTERACTION_SUBJECTTJPGIBS_STRING} (I: 850477faa7316bb65e6e0e370dc54f22)`); }\n subjectTjpGibsString = UNDEFINED_INTERACTION_SUBJECTTJPGIBS_STRING;\n } else {\n subjectTjpGibsString = subjectTjpGibs.join(DEFAULT_INTERACTION_SUBJECTTJPGIBS_DELIM)\n }\n\n if (addlDetailsText) {\n let saferAddlDetailsText = getSaferSubstring({ text: addlDetailsText, length: 64 });\n if (saferAddlDetailsText !== addlDetailsText) {\n console.warn(`${lc} using safer version of addlDetailsText: ${saferAddlDetailsText}. (W: b5516dabaeab4c93996e726e8feffe7f)`)\n addlDetailsText = saferAddlDetailsText;\n }\n }\n\n return addlDetailsText ?\n `${ROBBOT_INTERACTION_ATOM} ${data.type} ${timestampInTicks} ${subjectTjpGibsString} ${addlDetailsText}` :\n `${ROBBOT_INTERACTION_ATOM} ${data.type} ${timestampInTicks} ${subjectTjpGibsString}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function parseInteractionIb({\n ib,\n}: {\n ib: Ib,\n}): RobbotInteractionIbInfo {\n const lc = `[${parseInteractionIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ed5e959a2952fc6684a168ef8e9b6622)`); }\n const ibValidationErrors = validateIb({ ib }) ?? [];\n if (ibValidationErrors.length > 0) { throw new Error(`ib (${ib}) has validationErrors: ${ibValidationErrors} (E: c1b8c65524561ae67f58b237ba12fb22)`); }\n\n let [atom, type, timestampInTicks, subjectTjpGibsString, addlDetailsText] = ib.split(' ');\n if (atom !== ROBBOT_INTERACTION_ATOM) {\n console.warn(`${lc} atom !== default robbot interaction atom (${atom} !== ${ROBBOT_INTERACTION_ATOM}) (W: 9102868391174bbc90c54cb53726a4de)`);\n }\n if (!Object.values(RobbotInteractionType).includes((type as any))) {\n console.warn(`${lc} unknown robbot interaction type (${type}). (W: 68e85a9c495542f4a4a164752cc600e3)`);\n }\n let subjectTjpGibs: Gib[] | undefined = undefined;\n if (subjectTjpGibsString !== UNDEFINED_INTERACTION_SUBJECTTJPGIBS_STRING) {\n subjectTjpGibs =\n subjectTjpGibsString.split(DEFAULT_INTERACTION_SUBJECTTJPGIBS_DELIM).filter(x => !!x);\n const invalidTjpGibs = subjectTjpGibs.filter(gib => {\n const validationErrors = validateGib({ gib }) ?? [];\n if (validationErrors.length > 0) {\n console.error(`${lc} tjpGib (${gib}) has validation errors: ${validationErrors} (E: 679a654649ae4945932e85b3ded981be)`);\n return true;\n } else {\n return false;\n }\n });\n if (invalidTjpGibs.length > 0) { throw new Error(`ib contains invalid tjpGibs: ${invalidTjpGibs} (E: 7a5074e2e8685ec28c83954a1c12df22)`); }\n }\n\n return { atom, type, timestampInTicks, subjectTjpGibs, addlDetailsText };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function isInteraction({\n ibGib,\n ib,\n}: {\n ibGib?: IbGib_V1,\n ib?: Ib,\n}): boolean {\n const lc = `[${isInteraction.name}]`;\n try {\n ib = ib ?? ibGib?.ib;\n if (!ib) { throw new Error(`either ib or ibGib required (E: 15786fe75a5219ec7d925189f22d9f22)`); }\n let info = parseInteractionIb({ ib });\n return info.atom === ROBBOT_INTERACTION_ATOM;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n}\n\n/**\n * creates an ibgib stone (no tjp) that contains the interaction info.\n *\n * @returns interaction ibgib stone\n */\nexport async function getInteractionIbGib_V1({\n data,\n rel8ns,\n addlDetailsText,\n}: {\n /**\n * beginning data that may be mutated in this function.\n */\n data: RobbotInteractionData_V1,\n /**\n * beginning rel8ns that may be mutated in this function.\n */\n rel8ns?: RobbotInteractionRel8ns_V1,\n /**\n * for use in creating the ib per use case, if provided\n *\n * atow, I'm not using this.\n */\n addlDetailsText?: string,\n}): Promise<RobbotInteractionIbGib_V1> {\n const lc = `[${getInteractionIbGib_V1.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 138e6a406e1c600aad5b64e58a250922)`); }\n\n if (!data) { throw new Error(`data required (E: 7bdc46e1cfca9c286fc0dad9e8d60722)`); }\n\n if (!data.uuid) { data.uuid = await getUUID(); }\n\n rel8ns = rel8ns ?? {};\n rel8ns.ancestor = [`${ROBBOT_INTERACTION_ATOM}^${GIB}`];\n delete rel8ns.past;\n\n const ib = getInteractionIb({ data, addlDetailsText });\n\n const ibGib: RobbotInteractionIbGib_V1 = {\n ib, data, rel8ns,\n };\n ibGib.gib = await getGib({ ibGib, hasTjp: false });\n\n return ibGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getRobbotSessionIb({\n robbot,\n timestampInTicks,\n sessionId,\n contextTjpGib,\n addlMetadata,\n}: {\n robbot: IbGibRobbotAny,\n timestampInTicks: string,\n sessionId: string,\n contextTjpGib: Gib,\n addlMetadata?: string,\n}): string {\n const lc = `[${getRobbotSessionIb.name}]`;\n try {\n // validate\n if (logalot) { console.log(`${lc} starting... (I: 21206e0defe4bf23db96979fb456e822)`); }\n if (!robbot) { throw new Error(`robbot required (E: 200b32bbc4cac516e56d9561a9ffae22)`); }\n if (!robbot.data?.name) { throw new Error(`robbot.data.name required (E: d6470d5a146a1794811b9577ce881522)`); }\n if (!robbot.data.classname) { throw new Error(`robbot.data.classname required (E: 42077779c80889f1079e582d45932e22)`); }\n if (!robbot.data.uuid) { throw new Error(`robbot.data.uuid required (E: 34222f5639c329c99a2007ba6789bb22)`); }\n if (!timestampInTicks) { throw new Error(`timestampInTicks required (E: 17447cb30277af2beea8f2b13266c722)`); }\n if (!sessionId) { throw new Error(`sessionId required (E: 37a1737920996a55f311e79efe558422)`); }\n if (!contextTjpGib) { throw new Error(`contextTjpGib required (E: ad967964b764b077f448121e8b63c822)`); }\n if (addlMetadata) { if (!addlMetadata.match(/^\\w+$/)) { throw new Error(`addlMetadata must be alphanumerics only (E: 26f52b1378d1ad01f20f8ef5a5441722)`); } }\n\n // prepare\n const { name, classname, uuid } = robbot.data;\n const robbotTjpGib = getGibInfo({ gib: robbot.gib }).tjpGib;\n\n // main ib string\n let resultIb = `${ROBBOT_SESSION_ATOM} ${timestampInTicks} ${name} ${classname} ${uuid} ${robbotTjpGib} ${sessionId} ${contextTjpGib}`;\n\n // amend if addlMetadata provided\n if (addlMetadata) { resultIb += ` ${addlMetadata}`; }\n\n // returns\n return resultIb;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function parseRobbotSessionIb({\n ib,\n}: {\n ib: Ib,\n}): {\n timestamp: string,\n robbotName: string,\n robbotClassname: string,\n robbotId: string,\n robbotTjpGib: Gib,\n sessionId: string,\n contextTjpGib: Gib,\n addlMetadata: string,\n} {\n const lc = `[${parseRobbotSessionIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 21206e0defe4bf23db96979fb456e822)`); }\n if (!ib) { throw new Error(`ib required (E: c99627d871dbada4745474d9b63d4822)`); }\n\n const pieces = ib.split(' ');\n if (pieces.length !== 8 && pieces.length !== 9) { throw new Error(`invalid ib. should be space-delimited with 8 or 9 pieces, but there were ${pieces.length}. Expected pieces: atom, timestamp, robbotName, robbotClassname, robbotId, robbotTjpGib, sessionId, contextTjpGib, and optional addlMetadata. (E: 239ba7f599ce02a20271dd288c187d22)`); }\n\n const [_, timestamp, robbotName, robbotClassname, robbotId, robbotTjpGib, sessionId, contextTjpGib, addlMetadata] = ib.split(' ');\n return {\n timestamp,\n robbotName, robbotClassname, robbotId, robbotTjpGib,\n sessionId,\n contextTjpGib,\n addlMetadata\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "/**\n * @module subject constants\n *\n * witness constants are in this file!\n */\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// export const SOME_TYPE_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * atom used in ibs\n */\nexport const SUBJECT_ATOM = 'subject';\n\n/**\n * default regexp for a simple name string.\n */\nexport const SUBJECT_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\nexport const DEFAULT_NAME_SUBJECT = 'subject';\nexport const DEFAULT_UUID_SUBJECT = '';\nexport const DEFAULT_DESCRIPTION_SUBJECT = 'subject is a cool ibgib witness that has seriously fascinating behavior.';\n", "/**\n * @module observable constants\n *\n * witness constants are in this file!\n */\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// export const SOME_TYPE_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * atom used in ibs\n */\nexport const OBSERVABLE_ATOM = 'observable';\n\n/**\n * default regexp for a simple name string.\n */\nexport const OBSERVABLE_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\nexport const DEFAULT_UUID_OBSERVABLE = '';\nexport const DEFAULT_NAME_OBSERVABLE = 'observable';\nexport const DEFAULT_DESCRIPTION_OBSERVABLE = 'observable is a cool ibgib witness that has seriously fascinating behavior. this is an ibgibiffied pubsub implementation.';\n", "/**\n * @module observable types (and some enums/constants)\n */\n\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { WitnessWithContextData_V1, WitnessWithContextRel8ns_V1 } from '../../../witness/witness-with-context/witness-with-context-types.mjs';\nimport { WitnessCmdData, WitnessCmdIbGib, WitnessCmdRel8ns } from '../../../witness/witness-cmd/witness-cmd-types.mjs';\nimport { Witness, WitnessAny, WitnessFn, WitnessResultData, WitnessResultIbGib, WitnessResultRel8ns } from '../../../witness/witness-types.mjs';\nimport { DEFAULT_DESCRIPTION_OBSERVABLE, DEFAULT_NAME_OBSERVABLE, DEFAULT_UUID_OBSERVABLE } from './observable-constants.mjs';\nimport { SubscriptionIbGib_V1, SubscriptionWitness } from '../subscription/subscription-types.mjs';\nimport { Subscription_V1 } from '../subscription/subscription-v1.mjs';\nimport { ErrorIbGib_V1 } from '../../error/error-types.mjs';\nimport { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { ObserverWitness } from '../observer/observer-types.mjs';\n// and just to show where these things are\n// import { CommentIbGib_V1 } from \"@ibgib/core-gib/dist/common/comment/comment-types.mjs\";\n// import { MetaspaceService } from \"@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs\";\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// /**\n// * @see {@link SomeEnum}\n// */\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// /**\n// * values of {@link SomeEnum}\n// */\n// export const SOME_ENUM_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * ibgib's intrinsic data goes here.\n *\n * @see {@link IbGib_V1.data}\n */\nexport interface ObservableData_V1 extends WitnessWithContextData_V1 {\n // ibgib data (settings/values/etc) goes here\n // /**\n // * docs yo\n // */\n // setting: string;\n /**\n * if true, will replay previous events when subscribed.\n */\n replay?: boolean;\n}\n\n/**\n * rel8ns (named edges/links in DAG) go here.\n *\n * @see {@link IbGib_V1.rel8ns}\n */\nexport interface ObservableRel8ns_V1 extends WitnessWithContextRel8ns_V1 {\n // /**\n // * required rel8n. for most, put in observable-constants.mts file\n // *\n // * @see {@link REQUIRED_REL8N_NAME}\n // */\n // [REQUIRED_REL8N_NAME]: IbGibAddr[];\n // /**\n // * optional rel8n. for most, put in observable-constants.mts file\n // *\n // * @see {@link OPTIONAL_REL8N_NAME}\n // */\n // [OPTIONAL_REL8N_NAME]?: IbGibAddr[];\n}\n\n/**\n * this is the ibgib object itself.\n *\n * If this is a plain ibgib data only object, this acts as a dto. You may also\n * want to generate a witness ibgib, which is slightly different, for ibgibs\n * that will have behavior (i.e. methods).\n *\n * @see {@link ObservableData_V1}\n * @see {@link ObservableRel8ns_V1}\n */\nexport interface ObservableIbGib_V1 extends IbGib_V1<ObservableData_V1, ObservableRel8ns_V1> {\n\n}\n\n/**\n * Cmds for interacting with ibgib witnesses.\n\n * @see const {@link ObservableCmd} for individual jsdocs\n */\nexport type ObservableCmd =\n 'subscribe';\n/** Cmds for interacting with ibgib spaces. */\nexport const ObservableCmd = {\n /**\n * subscribe to the observable\n */\n subscribe: 'subscribe' as ObservableCmd,\n}\nexport const OBSERVABLE_CMD_VALUES: ObservableCmd[] = Object.values(ObservableCmd);\n\n/**\n * Flags to affect the command's interpretation.\n *\n * atow 11/2023 not used\n */\nexport type ObservableCmdModifier =\n 'ib' | 'gib' | 'ibgib';\n/**\n * Flags to affect the command's interpretation.\n *\n * atow 11/2023 not used\n */\nexport const ObservableCmdModifier = {\n /**\n * hmm...\n */\n ib: 'ib' as ObservableCmdModifier,\n /**\n * hmm...\n */\n gib: 'gib' as ObservableCmdModifier,\n /**\n * hmm...\n */\n ibgib: 'ibgib' as ObservableCmdModifier,\n}\n\n/** Information for interacting with spaces. */\nexport interface ObservableCmdData\n extends WitnessCmdData<ObservableCmd, ObservableCmdModifier> {\n}\n\nexport interface ObservableCmdRel8ns extends WitnessCmdRel8ns {\n}\n\n/**\n * Shape of options ibgib if used for a command-based witness.\n */\nexport interface ObservableCmdIbGib\n extends WitnessCmdIbGib<\n IbGib_V1,\n ObservableCmd, ObservableCmdModifier,\n ObservableCmdData, ObservableCmdRel8ns\n > {\n}\n\n/**\n * Optional shape of result data to witness interactions.\n *\n * This is in addition of course to {@link ObservableResultData}.\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * ## notes\n *\n * * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface ObservableResultData extends WitnessResultData {\n}\n\n/**\n * Marker interface rel8ns atm...\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface ObservableResultRel8ns extends WitnessResultRel8ns { }\n\n/**\n * Shape of result ibgib if used for a witness.\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface ObservableResultIbGib\n extends WitnessResultIbGib<IbGib_V1, ObservableResultData, ObservableResultRel8ns> {\n}\n\n/**\n * shape of underscore-delimited addl metadata string that may be present in the\n * ib (i.e. available when parsing the ib)\n *\n * This is not hard and fast and can (and should?) vary greatly per use case.\n */\nexport interface ObservableAddlMetadata {\n /**\n * should be observable\n */\n atom?: 'observable'\n /**\n * classname of observable **with any underscores removed**.\n */\n classnameIsh?: string;\n /**\n * name of observable witness (data.name) **with any underscores removed**.\n */\n nameIsh?: string;\n /**\n * id of witness (data.uuid) **with any underscores removed**.\n *\n * may be a substring per use case...?\n */\n idIsh?: string;\n}\n\n/**\n * Default data values for a Observable.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_OBSERVABLE_DATA_V1: ObservableData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_OBSERVABLE,\n name: DEFAULT_NAME_OBSERVABLE,\n description: DEFAULT_DESCRIPTION_OBSERVABLE,\n classname: `Observable_V1`,\n\n /**\n * if true, then the witness will attempt to persist ALL calls to\n * `witness.witness(...)`.\n */\n persistOptsAndResultIbGibs: false,\n /**\n * allow ibgibs like 42^gib ({ib: 42, gib: 'gib'} with `data` and `rel8ns` undefined)\n */\n allowPrimitiveArgs: true,\n /**\n * witnesses should be guaranteed not to throw uncaught exceptions.\n */\n catchAllErrors: false,\n /**\n * if true, would enable logging of all calls to `witness.witness(...)`\n */\n trace: false,\n\n // put in your custom defaults here\n}\nexport const DEFAULT_OBSERVABLE_REL8NS_V1: ObservableRel8ns_V1 | undefined = undefined;\n\n/**\n * v1 observABLE witness shape\n *\n * this is the \"future array\" that is being observed. it outputs a stream of\n * ibgibs, and can error and complete.\n *\n * @see {@link ObserverWitness}\n */\nexport interface ObservableWitness<\n TIbGibIn_ie_Payload extends IbGib_V1 = IbGib_V1,\n TIbGibOut_ie_ProbablyDontCare extends IbGib_V1 = IbGib_V1\n> extends WitnessAny {\n get isCompleteOrErrored(): boolean;\n get isComplete(): boolean;\n get isErrored(): boolean;\n /**\n * primary function to subscribe to new\n * @param witness ibgib to fire off when a new ibgib come downs the obsesrvable's pipe\n */\n subscribe(\n observer: WitnessAny | ObserverWitness<TIbGibIn_ie_Payload>\n ): Promise<SubscriptionWitness>;\n}\n\nexport interface ObservableWitnessAny extends ObservableWitness<any, any> { }\n", "/**\n * @module observer types (and some enums/constants)\n *\n * i don't have observers fleshed out like observables/subjects.\n *\n * i think this is more of list of shapes to be used by other concrete\n * observers, like subjects.\n */\n\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Witness, WitnessAny, } from '../../../witness/witness-types.mjs';\nimport { ErrorIbGib_V1 } from '../../error/error-types.mjs';\n\n\n\n/**\n * Plain-jane, non-witness version of observer shape.\n *\n * note that even though this isn't witness-based, it still is mostly\n * concerned with ibgibs as args. Where there are non-ibgib args,\n * this should be converted in the concrete implementor to an ibgib-wrapped\n * arg and passed to the `witness` function.\n *\n * @see {@link ObserverWitness}\n */\nexport interface Observer<T extends IbGib_V1 = IbGib_V1> {\n next(ibGib: T): Promise<void>;\n /**\n * @optional handler for an observable stream that produces an error.\n * @param error error or error ibgib produced when observable errors out\n */\n error?(error: string | Error | ErrorIbGib_V1): Promise<void>;\n complete?(): Promise<void>;\n}\n\n/**\n * v1 observER witness shape (as opposed to observABLE)\n *\n * this is the shape of the consumer's handler, usually an anonymous function.\n *\n * so when you subscribe to an observABLE witness, you pass in this shape which\n * will contain anonymous function ibgib witnesses.\n */\nexport interface ObserverWitness<TIbGibIn_ie_Payload extends IbGib_V1, TIbGibOut_ie_ProbablyDontCare extends IbGib_V1 = IbGib_V1>\n extends WitnessAny, Observer<TIbGibIn_ie_Payload> {\n}\n\n/** Cmds for interacting with ibgib observer witnesses. */\nexport type ObserverCmd =\n 'next' | 'error' | 'complete';\n/** Cmds for interacting with ibgib observer witnesses. */\nexport const ObserverCmd = {\n /**\n * it's more like a grunt that is intepreted by context.\n */\n next: 'next' as ObserverCmd,\n /**\n * it's more like a grunt that is intepreted by context.\n */\n error: 'error' as ObserverCmd,\n /**\n * indicate to complete the observable\n */\n complete: 'complete' as ObserverCmd,\n}\n", "/**\n * @module subject types (and some enums/constants)\n */\n\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\n\nimport { WitnessCmdData, WitnessCmdIbGib, WitnessCmdRel8ns } from '../../../witness/witness-cmd/witness-cmd-types.mjs';\nimport { WitnessResultData, WitnessResultIbGib, WitnessResultRel8ns } from '../../../witness/witness-types.mjs';\nimport { DEFAULT_DESCRIPTION_SUBJECT, DEFAULT_NAME_SUBJECT, DEFAULT_UUID_SUBJECT } from './subject-constants.mjs';\nimport {\n ObservableCmd,\n ObservableData_V1, ObservableRel8ns_V1,\n ObservableWitness,\n} from '../observable/observable-types.mjs';\nimport { ObserverCmd, ObserverWitness } from '../observer/observer-types.mjs';\n\n/**\n * ibgib's intrinsic data goes here.\n *\n * @see {@link IbGib_V1.data}\n */\nexport interface SubjectData_V1 extends ObservableData_V1 {\n // ibgib data (settings/values/etc) goes here\n // /**\n // * docs yo\n // */\n // setting: string;\n}\n\n/**\n * rel8ns (named edges/links in DAG) go here.\n *\n * @see {@link IbGib_V1.rel8ns}\n */\nexport interface SubjectRel8ns_V1 extends ObservableRel8ns_V1 {\n // /**\n // * required rel8n. for most, put in subject-constants.mts file\n // *\n // * @see {@link REQUIRED_REL8N_NAME}\n // */\n // [REQUIRED_REL8N_NAME]: IbGibAddr[];\n // /**\n // * optional rel8n. for most, put in subject-constants.mts file\n // *\n // * @see {@link OPTIONAL_REL8N_NAME}\n // */\n // [OPTIONAL_REL8N_NAME]?: IbGibAddr[];\n}\n\n/**\n * this is the ibgib object itself.\n *\n * If this is a plain ibgib data only object, this acts as a dto. You may also\n * want to generate a witness ibgib, which is slightly different, for ibgibs\n * that will have behavior (i.e. methods).\n *\n * @see {@link SubjectData_V1}\n * @see {@link SubjectRel8ns_V1}\n */\nexport interface SubjectIbGib_V1 extends IbGib_V1<SubjectData_V1, SubjectRel8ns_V1> {\n\n}\n\n/**\n * Cmds for interacting with ibgib subject witnesses.\n *\n * this is atow (11/2023) the union of `ObservableCmd` and `ObserverCmd`.\n *\n * @see {ObservableCmd}\n * @see {ObserverCmd}\n * */\nexport type SubjectCmd =\n ObservableCmd | ObserverCmd;\n/**\n * Cmds for interacting with ibgib subject witnesses.\n *\n * this is atow (11/2023) the union of `ObservableCmd` and `ObserverCmd`.\n *\n * @see {ObservableCmd}\n * @see {ObserverCmd}\n * */\nexport const SubjectCmd = {\n ...ObservableCmd,\n ...ObserverCmd,\n}\n\n/**\n * Flags to affect the command's interpretation.\n */\nexport type SubjectCmdModifier =\n 'ib' | 'gib' | 'ibgib';\n/**\n * Flags to affect the command's interpretation.\n */\nexport const SubjectCmdModifier = {\n /**\n * hmm...\n */\n ib: 'ib' as SubjectCmdModifier,\n /**\n * hmm...\n */\n gib: 'gib' as SubjectCmdModifier,\n /**\n * hmm...\n */\n ibgib: 'ibgib' as SubjectCmdModifier,\n}\n\n/** Information for interacting with spaces. */\nexport interface SubjectCmdData\n extends WitnessCmdData<SubjectCmd, SubjectCmdModifier> {\n}\n\nexport interface SubjectCmdRel8ns extends WitnessCmdRel8ns {\n}\n\n/**\n * Shape of options ibgib if used for a command-based witness.\n */\nexport interface SubjectCmdIbGib\n extends WitnessCmdIbGib<\n IbGib_V1,\n SubjectCmd, SubjectCmdModifier,\n SubjectCmdData, SubjectCmdRel8ns\n > {\n}\n\n/**\n * Optional shape of result data to witness interactions.\n *\n * This is in addition of course to {@link SubjectResultData}.\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * ## notes\n *\n * * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface SubjectResultData extends WitnessResultData {\n}\n\n/**\n * Marker interface rel8ns atm...\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface SubjectResultRel8ns extends WitnessResultRel8ns { }\n\n/**\n * Shape of result ibgib if used for a witness.\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface SubjectResultIbGib\n extends WitnessResultIbGib<IbGib_V1, SubjectResultData, SubjectResultRel8ns> {\n}\n\n/**\n * shape of underscore-delimited addl metadata string that may be present in the\n * ib (i.e. available when parsing the ib)\n *\n * This is not hard and fast and can (and should?) vary greatly per use case.\n */\nexport interface SubjectAddlMetadata {\n /**\n * should be subject\n */\n atom?: 'subject'\n /**\n * classname of subject **with any underscores removed**.\n */\n classnameIsh?: string;\n /**\n * name of subject witness (data.name) **with any underscores removed**.\n */\n nameIsh?: string;\n /**\n * id of witness (data.uuid) **with any underscores removed**.\n *\n * may be a substring per use case...?\n */\n idIsh?: string;\n}\n\n/**\n * Default data values for a Subject.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_SUBJECT_DATA_V1: SubjectData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_SUBJECT,\n name: DEFAULT_NAME_SUBJECT,\n description: DEFAULT_DESCRIPTION_SUBJECT,\n classname: `Subject_V1`,\n\n /**\n * if true, then the witness will attempt to persist ALL calls to\n * `witness.witness(...)`.\n */\n persistOptsAndResultIbGibs: false,\n /**\n * allow ibgibs like 42^gib ({ib: 42, gib: 'gib'} with `data` and `rel8ns` undefined)\n */\n allowPrimitiveArgs: true,\n /**\n * witnesses should be guaranteed not to throw uncaught exceptions.\n */\n catchAllErrors: true,\n /**\n * if true, would enable logging of all calls to `witness.witness(...)`\n */\n trace: false,\n\n // put in your custom defaults here\n}\nexport const DEFAULT_SUBJECT_REL8NS_V1: SubjectRel8ns_V1 | undefined = undefined;\n\n\n/**\n * Subject is both an observable stream and event producer\n */\nexport interface SubjectWitness<\n TIbGibIn_ie_Payload extends IbGib_V1 = IbGib_V1,\n TIbGibOut_ie_ProbablyDontCare extends IbGib_V1 = IbGib_V1\n> extends ObserverWitness<TIbGibIn_ie_Payload>,\n ObservableWitness<TIbGibIn_ie_Payload, TIbGibOut_ie_ProbablyDontCare> {\n asObservable(): ObservableWitness<TIbGibIn_ie_Payload, TIbGibOut_ie_ProbablyDontCare>;\n}\n", "/**\n * Used in ErrorIbGib_V1.ib\n */\nexport const DEFAULT_ERROR_MSG_IB_SUBSTRING_LENGTH = 20;\n/**\n * regexp for an error ibgib's (ErrorIbGib_V1) ib property.\n */\nexport const ERROR_IB_REGEXP = /^error (\\w+) ([a-fA-F\\d]{32}|undefined)$/;\n", "import { Ib } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\nimport { ErrorData_V1, ErrorIbGib_V1, ErrorRel8ns_V1 } from './error-types.mjs';\nimport { constantIbGib } from '../other/ibgib-helper.mjs';\nimport { DEFAULT_ERROR_MSG_IB_SUBSTRING_LENGTH, ERROR_IB_REGEXP } from './error-constants.mjs';\nimport {\n ERROR_MSG_LOCATION_ONLY_REGEXP, ERROR_MSG_WITH_ID_CAPTURE_GROUPS_REGEXP\n} from '@ibgib/helper-gib/dist/constants.mjs';\n\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * Generates an ib based on a raw error msg.\n *\n * ## future\n *\n * If this is changed in the future, then without versioning of some sort, this\n * will change the error constant ibgibs that rely on this functions\n * deterministic qualities.\n *\n * @returns the error's `ib`\n */\nexport function getErrorIb({\n rawMsg,\n}: {\n rawMsg: string,\n}): Ib {\n const lc = `[${getErrorIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const parsed = parseRawErrorMsg({ rawMsg });\n const saferText = parsed.body.replace(/\\s/g, '_').replace(/\\W/g, '');\n let msgSlice: string;\n if (saferText.length > DEFAULT_ERROR_MSG_IB_SUBSTRING_LENGTH) {\n msgSlice =\n saferText.substring(0, DEFAULT_ERROR_MSG_IB_SUBSTRING_LENGTH);\n } else if (saferText.length > 0) {\n msgSlice = saferText;\n } else {\n // msg only has characters/nonalphanumerics ?\n throw new Error(`(UNEXPECTED) error msg should have characters/alphanumerics... (E: a3b9cd11a44cc7892a748819c2885422)`);\n }\n\n return `error ${msgSlice} ${parsed.uuid ?? 'undefined'}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Parses a raw error/exception message.\n *\n * If it has sections that I personally use (usually), then it will break that\n * out. otherwise, it will just have the `rawMsg` as the msg body and raw msg.\n *\n * @see {@link ErrorData_V1}\n */\nexport function parseRawErrorMsg({\n rawMsg,\n}: {\n rawMsg: string,\n}): ErrorData_V1 {\n const lc = `[${parseRawErrorMsg.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!rawMsg) { throw new Error(`(UNEXPECTED) rawMsg required (E: e5bd3b433a1781ebe885534cd2495622)`); }\n\n let data: ErrorData_V1;\n let regexResult = rawMsg.match(ERROR_MSG_WITH_ID_CAPTURE_GROUPS_REGEXP);\n if (regexResult) {\n // has id section\n const [_, location, unexpectedAtStart, body, idSection, unexpectedAtEnd] = regexResult;\n if (!body) { throw new Error(`invalid error msg body (E: a675e6855cca96519d33d44ea5400922)`); }\n data = {\n success: false,\n raw: rawMsg,\n body: body?.trim(),\n uuid: idSection.slice(4, 36),\n };\n if (location) { data.location = location; }\n if (unexpectedAtStart || unexpectedAtEnd) { data.unexpected = true; }\n } else {\n // no id or unexpected regex (maybe changed?)\n data = {\n success: false,\n raw: rawMsg,\n body: rawMsg,\n };\n let regexResultLocation = rawMsg.match(ERROR_MSG_LOCATION_ONLY_REGEXP);\n if (regexResultLocation) {\n const [_, location] = regexResultLocation;\n data.location = location;\n }\n if (rawMsg.toLowerCase().includes(`(unexpected)`)) {\n data.unexpected = true;\n }\n }\n\n return data;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Builds a \"constant\" error ibgib based on the given `rawMsg`.\n *\n * @returns constant error ibgib built from given `rawMsg`\n *\n * @see {@link ErrorData_V1}\n * @see {@link ErrorIbGib_V1}\n */\nexport function getErrorIbGib({ rawMsg }: { rawMsg: string }): Promise<ErrorIbGib_V1> {\n const lc = `[${getErrorIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n return constantIbGib<ErrorData_V1, ErrorRel8ns_V1>({\n parentPrimitiveIb: 'error',\n ib: getErrorIb({ rawMsg }),\n data: parseRawErrorMsg({ rawMsg }),\n ibRegExpPattern: ERROR_IB_REGEXP.source,\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function isError({\n ibGib\n}: {\n ibGib: IbGib_V1\n}): boolean {\n const lc = `[${isError.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!ibGib) { throw new Error(`ibGib required (E: 1d756fbbd96f1734b97ba013537ed522)`); }\n return ibGib.ib.startsWith('error ');\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "/**\n * @module witness-factory-base\n *\n * this was a probably-klugy plumbing attempt for ionic-gib to instantiate ibgib\n * witness objects.\n *\n * Specifically this was to go from angular forms to witness ibgibs. The trick\n * was that ibgib's are data objects and you had to load the witness ibgibs\n * which actually had functions/methods on them.\n *\n * So the workflow was you get a form component with some fields, and you\n * generate the witness via this factory.\n *\n * it worked, but it's not strong I don't think.\n *\n * the main weak point is that i didn't fill out the form-items enough and i\n * never got it so that you could create nested forms.\n *\n * in its favor, i do use this (although klugily) in the ibgib rcli app, where\n * instead of a visual form it prompts the user. terrible ux but it did \"work\"\n * as a quick and dirty implementation. it could be polished going forward (i\n * dont think the design is inherently flawed).\n */\n\nimport { IbGibRel8ns_V1, IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { TransformResult } from \"@ibgib/ts-gib/dist/types.mjs\";\n\nimport { Witness, WitnessData_V1, WitnessRel8ns_V1 } from \"../witness-types.mjs\";\n\n// import * as c from '../constants';\n\n// const logalot = c.GLOBAL_LOG_A_LOT || false;\n\n/**\n * The idea is that any model can be injected via this factory provider.\n */\nexport abstract class WitnessFactoryBase<\n TWitnessData extends WitnessData_V1,\n TWitnessRel8ns extends WitnessRel8ns_V1,\n TWitness extends Witness<IbGib_V1, IbGib_V1, TWitnessData, TWitnessRel8ns>\n> {\n protected lc: string = `[${WitnessFactoryBase.name}]`;\n\n /**\n * override this to provide the name of the class for the factory.\n *\n * ## usage\n *\n * atm I'm using this to return the classname for the witness.\n *\n * @example MyWitnessClass.classname\n */\n abstract getName(): string;\n\n /**\n * creates a new witness. This should return the transform result with the\n * new ibgib being the witness class itself, not just the ibgib dto.\n *\n * So said in another way, the `result.newIbGib` should include the class\n * instantiation which has the `witness` function on it.\n *\n * @see {@link WitnessB}\n */\n abstract newUp({ data, rel8ns }: { data?: TWitnessData, rel8ns?: TWitnessRel8ns }):\n Promise<TransformResult<TWitness>>;\n\n}\n\nexport type WitnessFactoryAny = WitnessFactoryBase<any, any, any>;\n", "/**\n * @module dynamic-form-factory-base\n *\n *\n * @see {@link WitnessFactoryBase}\n */\n\nimport { patchObject } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { TransformResult } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { IbGibRel8ns_V1, IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\nimport { DynamicForm, FormItemInfo } from \"../../common/form/form-items.mjs\";\nimport { WitnessFactoryBase } from \"./witness-factory-base.mjs\";\nimport { Witness, WitnessData_V1, WitnessRel8ns_V1 } from \"../witness-types.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../../core-constants.mjs\";\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\n/**\n * The idea is that any model can be injected via this factory provider.\n *\n * So when you create a witness that you want to be able to instantiate via\n * just metadata, you also provide an accompanying factory that knows\n * how to map from a\n * * witness(model) -> form data (to generate dynamic forms)\n * * form data -> witness (to instantiate witness from data)\n */\nexport abstract class DynamicFormFactoryBase<\n TWitnessData extends WitnessData_V1,\n TWitnessRel8ns extends WitnessRel8ns_V1,\n TWitness extends Witness<IbGib_V1, IbGib_V1, TWitnessData, TWitnessRel8ns>\n>\n extends WitnessFactoryBase<TWitnessData, TWitnessRel8ns, TWitness>{\n protected lc: string = `[${DynamicFormFactoryBase.name}]`;\n /**\n * override this with something that maps from the ibgib/model to the form infos.\n */\n abstract witnessToForm({ witness }: { witness: TWitness }): Promise<DynamicForm>;\n /**\n * override this with specific behavior that will reify an instance based on\n * the given {@link form}.\n */\n abstract formToWitness({ form }: { form: DynamicForm }): Promise<TransformResult<TWitness>>;\n\n /**\n * iterates through the given {@link items}.\n *\n * If the item has child items, it is considered a grouping (i.e. FormGroup\n * or FormArray) and this function is called recursively with the\n * {@link contextPath} adjusted per the {@link pathDelimiter} and\n * `item.name`.\n *\n * If the item does not have child items, it's considered to be a setting at\n * the current path level and it's value is assigned per its `item.name` as\n * the key.\n */\n protected patchDataFromItems({\n data,\n contextPath,\n items,\n pathDelimiter,\n }: {\n /**\n * ibgib.data object that we are patching/setting from the form items.\n */\n data: any,\n /**\n * source items whose values we are patching the {@link data} with.\n */\n items: FormItemInfo[],\n /**\n * Separates sections of pathing into the data object.\n *\n * @default @see {@link DEFAULT_DATA_PATH_DELIMITER}\n */\n pathDelimiter: string,\n /**\n * we're patching the data object as follows:\n *\n * data[contextPath/item.name] = value\n *\n * where the '/' is the data path delimiter.\n *\n * So if the incoming items are nested deeper, this will look like\n *\n * data['mysetting/subsetting/color'] = \"red\"\n *\n * @see {@link pathDelimiter}\n * @see {@link DEFAULT_DATA_PATH_DELIMITER}\n */\n contextPath?: string,\n }): void {\n const lc = `${this.lc}[${this.patchDataFromItems.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!pathDelimiter) { throw new Error(`pathDelimiter required (E: 958d472a15fb71e45cd2925883f2ec22)`); }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const path = contextPath ?\n contextPath + pathDelimiter + item.name :\n item.name;\n if (!item.items) {\n // it's a property (FormControl, not FormGroup/Array)\n patchObject({\n obj: data,\n value: item.value,\n path,\n logalot,\n pathDelimiter,\n });\n } else if (item.items.length > 0) {\n // it's a group, so call this function recursively\n this.patchDataFromItems({\n data,\n contextPath: path,\n items: item.items,\n pathDelimiter,\n });\n } else {\n throw new Error(`invalid item. items is truthy but with a length of 0. items should either be falsy or have at least one child. (E: ee2765e0b920477f919fcb09e9d951b4)`);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n}\n", "import { clone, getUUID, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getGib, IbGib_V1, IbGibRel8ns_V1, } from '@ibgib/ts-gib/dist/V1/index.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport { WitnessData_V1, Witness_V1, } from './witness-types.mjs';\nimport { toDto } from '../common/other/ibgib-helper.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || false;\n\nexport abstract class LightWitnessBase_V1<\n TData extends WitnessData_V1 = WitnessData_V1,\n TRel8ns extends IbGibRel8ns_V1 = IbGibRel8ns_V1\n>\n implements Witness_V1<\n any, any, IbGib_V1, // options arg can be any ibgib\n any, any, IbGib_V1, // result can be any ibgib\n TData, TRel8ns // this witness itself\n > {\n\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${LightWitnessBase_V1.name}]`;\n\n public instanceId: string = '';\n\n // #region IbGib interface fields: ib, gib, data, rel8ns\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n ib: string = '';\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n gib: string | undefined;\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n data: TData | undefined;\n\n /**\n * Used per use case in implementing class.\n *\n * This property is a simple property (no getter/setter with backing\n * fields). This is to simplify usage with DTOs (Data Transfer Objects) for\n * storing in spaces.\n */\n rel8ns: TRel8ns | undefined;\n\n // #endregion IbGib interface fields: ib, gib, data, rel8ns\n\n /**\n * await this to ensure the witness is ready.\n *\n * This is called in the base `Witness.witness` function before `witnessImpl`.\n */\n initialized: Promise<void> | undefined;\n /**\n * synchronous and faster boolean for checking faster.\n *\n * so normally, do a check like...\n * if (!this._isInitialized) { await this.initialized; }\n */\n protected _isInitialized: boolean = false;\n\n constructor(initialData?: TData, initialRel8ns?: TRel8ns) {\n if (initialData) { this.data = initialData; }\n if (initialRel8ns) { this.rel8ns = initialRel8ns; }\n this.initialized = this.initialize().then(() => { this._isInitialized = true });\n }\n\n /**\n * by default, simply returns true atow in base class.\n * override this to perform code before any other code is executed.\n */\n protected async initialize(): Promise<void> {\n this.instanceId = await getUUID();\n this.gib = await getGib({ ibGib: this.toIbGibDto() });\n }\n\n /**\n * Creates a data transfer object (dto) snapshot out of this\n * witness' `ib`, `gib`, `data` and `rel8ns` properties.\n *\n * I say \"snapshot\" because this copies each property\n * (`ib`, `gib`, `data`, `rel8ns`).\n *\n * ## thoughts\n *\n * Witness classes need to be able to persist their ibgib\n * just as regular data. But witnesses have the additional\n * layer of behavior (e.g. the `witness` function) that\n * will not persist (until we get more integrated version control\n * types of functionality in ibgib).\n *\n * @returns dto ibgib object with just clones of this.ib/gib/data/rel8ns props.\n *\n * @see {loadIbGibDto}\n */\n toIbGibDto(): IbGib_V1<TData, TRel8ns> {\n return toDto({ ibGib: this });\n }\n\n /**\n * (Re)hydrates this witness class with the ibgib information from the dto.\n *\n * ## notes\n *\n * * You can extend this function for witness-specific behavior when loading.\n *\n * @param dto ib, gib, data & rel8ns to load for this witness ibgib instance.\n *\n * @see {toIbGibDto}\n */\n loadIbGibDto(dto: IbGib_V1<TData, TRel8ns>): Promise<void> {\n const lc = `${this.lc}[${this.loadIbGibDto.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!dto.ib) { console.warn(`${lc} dto.ib is falsy.`); }\n if (!dto.gib) { console.warn(`${lc} dto.gib is falsy.`); }\n\n this.ib = clone(dto.ib);\n this.gib = clone(dto.gib);\n if (dto.data) {\n this.data = clone(dto.data);\n } else {\n delete this.data;\n }\n if (dto.rel8ns) { this.rel8ns = clone(dto.rel8ns); } else { delete this.rel8ns; }\n\n return Promise.resolve();\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * The primary function of a witness is...well... to witness things.\n *\n * So this is the base implementation that includes validation\n * plumbing, tracing, error checking/catching - all depending\n * on witness configuration.\n *\n *\n * ## usage\n *\n * Only override this function if you really want custom handling of\n * the plumbing. Instead override `witnessImpl`.\n *\n * {@see validateThis}\n * {@see validateWitnessArg}\n *\n * @param arg\n * @returns\n */\n abstract witness(arg: IbGib_V1): Promise<IbGib_V1 | undefined>;\n\n /**\n * Validate this witness object, checking its own `data` and `rel8ns`, and\n * possibly other state.\n *\n * ## notes\n *\n * ATOW base implementation of this just checks for non-falsy\n * `this.ib` and `this.gib`\n */\n protected async validateThis(): Promise<string[]> {\n const lc = `${this.lc}[${this.validateThis.name}]`;\n const errors: string[] = [];\n try {\n if (!this.ib) { errors.push(`this.ib is falsy.`); }\n if (!this.gib) { errors.push(`this.gib is falsy.`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n return errors;\n }\n\n}\n\n/**\n * LightWitness with `any` types in generic.\n */\nexport type LightWitnessAny = LightWitnessBase_V1<any, any>;\n", "/**\n * @module subscription constants\n *\n * witness constants are in this file!\n */\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// export const SOME_TYPE_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * atom used in ibs\n */\nexport const SUBSCRIPTION_ATOM = 'subscription';\n\n/**\n * default regexp for a simple name string.\n */\nexport const SUBSCRIPTION_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\nexport const DEFAULT_UUID_SUBSCRIPTION = '';\nexport const DEFAULT_NAME_SUBSCRIPTION = 'subscription';\nexport const DEFAULT_DESCRIPTION_SUBSCRIPTION = 'subscription is a cool ibgib witness that has seriously fascinating behavior.';\n", "/**\n * @module subscription types (and some enums/constants)\n */\n\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { WitnessWithContextData_V1, WitnessWithContextRel8ns_V1 } from '../../../witness/witness-with-context/witness-with-context-types.mjs';\nimport { WitnessCmdData, WitnessCmdIbGib, WitnessCmdRel8ns } from '../../../witness/witness-cmd/witness-cmd-types.mjs';\nimport { Witness, WitnessAny, WitnessResultData, WitnessResultIbGib, WitnessResultRel8ns } from '../../../witness/witness-types.mjs';\nimport { DEFAULT_DESCRIPTION_SUBSCRIPTION, DEFAULT_NAME_SUBSCRIPTION, DEFAULT_UUID_SUBSCRIPTION } from './subscription-constants.mjs';\n// and just to show where these things are\n// import { CommentIbGib_V1 } from \"@ibgib/core-gib/dist/common/comment/comment-types.mjs\";\n// import { MetaspaceService } from \"@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs\";\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// /**\n// * @see {@link SomeEnum}\n// */\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// /**\n// * values of {@link SomeEnum}\n// */\n// export const SOME_ENUM_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * ibgib's intrinsic data goes here.\n *\n * @see {@link IbGib_V1.data}\n */\nexport interface SubscriptionData_V1 extends WitnessWithContextData_V1 {\n // ibgib data (settings/values/etc) goes here\n // /**\n // * docs yo\n // */\n // setting: string;\n // createdTimestamp: string;\n // unsubscribedTimestamp: string;\n}\n\n/**\n * rel8ns (named edges/links in DAG) go here.\n *\n * @see {@link IbGib_V1.rel8ns}\n */\nexport interface SubscriptionRel8ns_V1 extends WitnessWithContextRel8ns_V1 {\n // /**\n // * required rel8n. for most, put in subscription-constants.mts file\n // *\n // * @see {@link REQUIRED_REL8N_NAME}\n // */\n // [REQUIRED_REL8N_NAME]: IbGibAddr[];\n // /**\n // * optional rel8n. for most, put in subscription-constants.mts file\n // *\n // * @see {@link OPTIONAL_REL8N_NAME}\n // */\n // [OPTIONAL_REL8N_NAME]?: IbGibAddr[];\n}\n\n/**\n * this is the ibgib object itself.\n *\n * If this is a plain ibgib data only object, this acts as a dto. You may also\n * want to generate a witness ibgib, which is slightly different, for ibgibs\n * that will have behavior (i.e. methods).\n *\n * @see {@link SubscriptionData_V1}\n * @see {@link SubscriptionRel8ns_V1}\n */\nexport interface SubscriptionIbGib_V1 extends IbGib_V1<SubscriptionData_V1, SubscriptionRel8ns_V1> {\n\n}\n\nexport type SubscriptionCmd =\n 'unsubscribe' | 'unsubscribed';\n/** Cmds for interacting with ibgib spaces. */\nexport const SubscriptionCmd = {\n /**\n * unsubscribe from the subscription's associated observable (that generated\n * this subscription).\n */\n unsubscribe: 'unsubscribe' as SubscriptionCmd,\n /**\n * returns boolean if this subscription is still actively subscribed to the\n * associated observable (that generated this subscription).\n */\n unsubscribed: 'unsubscribed' as SubscriptionCmd,\n}\n\n/**\n * Flags to affect the command's interpretation.\n */\nexport type SubscriptionCmdModifier =\n 'ib' | 'gib' | 'ibgib';\n/**\n * Flags to affect the command's interpretation.\n */\nexport const SubscriptionCmdModifier = {\n /**\n * hmm...\n */\n ib: 'ib' as SubscriptionCmdModifier,\n /**\n * hmm...\n */\n gib: 'gib' as SubscriptionCmdModifier,\n /**\n * hmm...\n */\n ibgib: 'ibgib' as SubscriptionCmdModifier,\n}\n\n/** Information for interacting with spaces. */\nexport interface SubscriptionCmdData\n extends WitnessCmdData<SubscriptionCmd, SubscriptionCmdModifier> {\n}\n\nexport interface SubscriptionCmdRel8ns extends WitnessCmdRel8ns {\n}\n\n/**\n * Shape of options ibgib if used for a command-based witness.\n */\nexport interface SubscriptionCmdIbGib\n extends WitnessCmdIbGib<\n IbGib_V1,\n SubscriptionCmd, SubscriptionCmdModifier,\n SubscriptionCmdData, SubscriptionCmdRel8ns\n > {\n}\n\n/**\n * Optional shape of result data to witness interactions.\n *\n * This is in addition of course to {@link SubscriptionResultData}.\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * ## notes\n *\n * * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface SubscriptionResultData extends WitnessResultData {\n}\n\n/**\n * Marker interface rel8ns atm...\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface SubscriptionResultRel8ns extends WitnessResultRel8ns { }\n\n/**\n * Shape of result ibgib if used for a witness.\n *\n * so if you're sending a cmd to this witness, this should probably be the shape\n * of the result.\n *\n * I'm not sure what to do with this atm, so I'm just stubbing out...\n */\nexport interface SubscriptionResultIbGib\n extends WitnessResultIbGib<IbGib_V1, SubscriptionResultData, SubscriptionResultRel8ns> {\n}\n\n/**\n * shape of underscore-delimited addl metadata string that may be present in the\n * ib (i.e. available when parsing the ib)\n *\n * This is not hard and fast and can (and should?) vary greatly per use case.\n */\nexport interface SubscriptionAddlMetadata {\n /**\n * should be subscription\n */\n atom?: 'subscription'\n /**\n * classname of subscription **with any underscores removed**.\n */\n classnameIsh?: string;\n /**\n * name of subscription witness (data.name) **with any underscores removed**.\n */\n nameIsh?: string;\n /**\n * id of witness (data.uuid) **with any underscores removed**.\n *\n * may be a substring per use case...?\n */\n idIsh?: string;\n}\n\n/**\n * Default data values for a Subscription.\n *\n * If you change this, please bump the version\n *\n * (but of course won't be the end of the world when this doesn't happen).\n */\nexport const DEFAULT_SUBSCRIPTION_DATA_V1: SubscriptionData_V1 = {\n version: '1',\n uuid: DEFAULT_UUID_SUBSCRIPTION,\n name: DEFAULT_NAME_SUBSCRIPTION,\n description: DEFAULT_DESCRIPTION_SUBSCRIPTION,\n classname: `Subscription_V1`,\n\n /**\n * if true, then the witness will attempt to persist ALL calls to\n * `witness.witness(...)`.\n */\n persistOptsAndResultIbGibs: false,\n /**\n * allow ibgibs like 42^gib ({ib: 42, gib: 'gib'} with `data` and `rel8ns` undefined)\n */\n allowPrimitiveArgs: true,\n /**\n * witnesses should be guaranteed not to throw uncaught exceptions.\n */\n catchAllErrors: false,\n /**\n * if true, would enable logging of all calls to `witness.witness(...)`\n */\n trace: false,\n\n // put in your custom defaults here\n}\nexport const DEFAULT_SUBSCRIPTION_REL8NS_V1: SubscriptionRel8ns_V1 | undefined = undefined;\n\n/**\n * v1 subscription witness shape\n */\nexport interface SubscriptionWitness extends WitnessAny {\n /**\n * unsubscribe a subscriber of an observable via this subscription.\n * see `Subscription_V1`\n */\n unsubscribe(): Promise<void>;\n /**\n * flag to indicate if a subscription is still active or not.\n * see `Subscription_V1`\n */\n unsubscribed(): Promise<boolean>;\n}\n", "/*\n * @module observable helper/util/etc. functions\n *\n * this is where you will find helper functions like those that generate\n * and parse ibs for observable.\n */\n\n// import * as pathUtils from 'path';\n// import { statSync } from 'node:fs';\n// import { readFile, } from 'node:fs/promises';\n// import * as readline from 'node:readline/promises';\n// import { stdin, stdout } from 'node:process'; // decide if use this or not\n\nimport {\n extractErrorMsg, delay, getSaferSubstring,\n getTimestampInTicks, getUUID, pretty,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { UUID_REGEXP, CLASSNAME_REGEXP, } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { validateIbGibIntrinsically, } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport { WitnessFormBuilder } from '../../../witness/witness-form-builder.mjs';\n// import { IbGibObservableAny } from './observable-v1.mjs';\nimport {\n ObservableData_V1, ObservableRel8ns_V1, ObservableIbGib_V1,\n} from './observable-types.mjs';\nimport { OBSERVABLE_NAME_REGEXP, } from './observable-constants.mjs';\nimport { OBSERVABLE_ATOM } from './observable-constants.mjs';\nimport { SUBJECT_ATOM } from '../subject/subject-constants.mjs';\n\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport function validateCommonObservableData({\n data,\n}: {\n data?: ObservableData_V1,\n}): string[] {\n const lc = `[${validateCommonObservableData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!data) { throw new Error(`Observable Data required (E: 6d1c97931dcab8ea9f3e9b32c794b90c)`); }\n const errors: string[] = [];\n const {\n name, uuid, classname,\n } =\n data;\n\n if (name) {\n if (!name.match(OBSERVABLE_NAME_REGEXP)) {\n errors.push(`name must match regexp: ${OBSERVABLE_NAME_REGEXP} (E: 21bf77e398d47e9d035376510505eda2)`);\n }\n } else {\n errors.push(`name required.`);\n }\n\n if (uuid) {\n if (!uuid.match(UUID_REGEXP)) {\n errors.push(`uuid must match regexp: ${UUID_REGEXP} (E: e53fd08ae69e945b37ed895b864b6bd7)`);\n }\n } else {\n errors.push(`uuid required.`);\n }\n\n if (classname) {\n if (!classname.match(CLASSNAME_REGEXP)) {\n errors.push(`classname must match regexp: ${CLASSNAME_REGEXP}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateCommonObservableIbGib({\n ibGib,\n}: {\n ibGib: ObservableIbGib_V1,\n}): Promise<string[] | undefined> {\n const lc = `[${validateCommonObservableIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 53696a50efff60fd86a2f431dae6ac67)`); }\n const intrinsicErrors: string[] = await validateIbGibIntrinsically({ ibGib }) ?? [];\n\n if (!ibGib.data) { throw new Error(`ibGib.data required (E: 5bae607c41ed4de40ec333a40673bdb8)`); }\n const ibErrors: string[] = [];\n let { ObservableClassname, ObservableName, ObservableId } =\n parseObservableIb({ ib: ibGib.ib });\n if (!ObservableClassname) { ibErrors.push(`ObservableClassname required (E: 029f7a2405c4b7aa1f52711586f8ebfd)`); }\n if (!ObservableName) { ibErrors.push(`ObservableName required (E: e68cbc6f3183169c35117184f610573e)`); }\n if (!ObservableId) { ibErrors.push(`ObservableId required (E: 0516442854be7ec32f5928b4cf2697f7)`); }\n\n const dataErrors = validateCommonObservableData({ data: ibGib.data });\n\n let result = [...(intrinsicErrors ?? []), ...(ibErrors ?? []), ...(dataErrors ?? [])];\n if (result.length > 0) {\n return result;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getObservableIb({\n data,\n classname,\n}: {\n data: ObservableData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getObservableIb.name}]`;\n try {\n const validationErrors = validateCommonObservableData({ data });\n if (validationErrors.length > 0) { throw new Error(`invalid Observable data: ${validationErrors} (E: fd6b0b32d8f6c4b97eebd489cdb07a4a)`); }\n if (classname) {\n if (data.classname && data.classname !== classname) { throw new Error(`classname does not match data.classname (E: 354285a56a20b9b65b06abfcd9f2e621)`); }\n } else {\n classname = data.classname;\n if (!classname) { throw new Error(`classname required (E: 040c1fd71853fa7874146999afb355c3)`); }\n }\n\n // ad hoc validation here. should centralize witness classname validation\n\n const { name, uuid } = data;\n return `witness ${OBSERVABLE_ATOM} ${classname} ${name} ${uuid}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Current schema is 'witness [OBSERVABLE_ATOM] [classname] [ObservableName] [ObservableId]'\n *\n * NOTE this is space-delimited\n */\nexport function parseObservableIb({\n ib,\n}: {\n ib: Ib,\n}): {\n ObservableClassname: string,\n ObservableName: string,\n ObservableId: string,\n} {\n const lc = `[${parseObservableIb.name}]`;\n try {\n if (!ib) { throw new Error(`Observable ib required (E: 84156af64e73d479220a36f247466659)`); }\n\n const pieces = ib.split(' ');\n\n return {\n ObservableClassname: pieces[2],\n ObservableName: pieces[3],\n ObservableId: pieces[4],\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport class ObservableFormBuilder extends WitnessFormBuilder {\n protected lc: string = `[${ObservableFormBuilder.name}]`;\n\n constructor() {\n super();\n this.what = 'observable';\n }\n\n // exampleSetting({\n // of,\n // required,\n // }: {\n // of: string,\n // required?: boolean,\n // }): ObservableFormBuilder {\n // this.addItem({\n // // Observable.data.exampleSetting\n // name: \"exampleSetting\",\n // description: `example description`,\n // label: \"Example Label\",\n // regexp: EXAMPLE_REGEXP,\n // regexpErrorMsg: EXAMPLE_REGEXP_DESC,\n // dataType: 'textarea',\n // value: of,\n // required,\n // });\n // return this;\n // }\n\n}\n\n/**\n * helper to determine if an ibGib is observable.\n *\n * atow 11/2023 just checks ib for presence of either SUBJECT_ATOM or OBSERVABLE_ATOM\n *\n * @returns true if observable witness, else false.\n */\nexport function isObservable({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): boolean {\n const lc = `[${isObservable.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3aadb634377acbe42984b61c91975323)`); }\n const { ib } = ibGib;\n const observableAtoms = [OBSERVABLE_ATOM, SUBJECT_ATOM];\n return observableAtoms.some(atom => ib.includes(atom));\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "/**\n * @module Subscription_V1 witness class\n *\n * this is where you will find the witness class that contains behavior\n * for the Subscription ibgib.\n *\n * A subscription can do two things from the caller's side:\n *\n * 1. unsubscribe\n * 2. give a boolean on whether it has been unsubscribed or not\n *\n * A subscription is created from a call to subscribe on an observable. Since\n * the observable is also a witness, we can have this subscription visit the\n * observable via `observable.witness(subscription)`. IOW, the subscription\n * witness ibgib is the argument to `witness` function.\n *\n * The observable will know that if a subscription visits it, then the\n * observable needs to release/unsubscribe that subscription.\n *\n * So since this is a light witness, we can just have two primitives be the\n * incoming argument ibgibs: unsubscribe^gib and unsubscribed^gib.\n */\n\nimport {\n extractErrorMsg, delay, getSaferSubstring,\n getTimestampInTicks, getUUID, pretty, clone, getIdPool,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { DEFAULT_DATA_PATH_DELIMITER } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { IbGib_V1, Rel8n, } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Factory_V1, } from '@ibgib/ts-gib/dist/V1/factory.mjs';\nimport { TransformResult } from '@ibgib/ts-gib/dist/types.mjs';\nimport { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\n\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';\nimport { argy_, isArg, isCommand, resulty_ } from '../../../witness/witness-helper.mjs';\nimport { isError } from '../../error/error-helper.mjs';\nimport { DynamicFormBuilder } from '../../form/form-helper.mjs';\nimport { WitnessFormBuilder } from '../../../witness/witness-form-builder.mjs';\nimport { DynamicFormFactoryBase } from '../../../witness/factory/dynamic-form-factory-base.mjs';\nimport { DynamicForm } from '../../form/form-items.mjs';\nimport {\n SubscriptionData_V1, SubscriptionRel8ns_V1, SubscriptionIbGib_V1,\n SubscriptionCmd, SubscriptionCmdData, SubscriptionCmdRel8ns, SubscriptionCmdIbGib,\n SubscriptionResultData, SubscriptionResultRel8ns, SubscriptionResultIbGib,\n SubscriptionAddlMetadata,\n DEFAULT_SUBSCRIPTION_DATA_V1,\n DEFAULT_SUBSCRIPTION_REL8NS_V1,\n SubscriptionWitness,\n} from './subscription-types.mjs';\nimport { SubscriptionFormBuilder, getSubscriptionIb } from './subscription-helper.mjs';\nimport { DEFAULT_DESCRIPTION_SUBSCRIPTION, DEFAULT_NAME_SUBSCRIPTION, SUBSCRIPTION_ATOM } from './subscription-constants.mjs';\nimport { LightWitnessBase_V1 } from '../../../witness/light-witness-base-v1.mjs';\nimport { FALSE_GIB, TRUE_GIB } from '../../other/ibgib-constants.mjs';\nimport { ErrorIbGib_V1 } from '../../error/error-types.mjs';\nimport { getGib } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { constantIbGib } from '../../other/ibgib-helper.mjs';\nimport { isObservable } from '../observable/observable-helper.mjs';\nimport { ObservableWitnessAny } from '../observable/observable-types.mjs';\n\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT; // change this when you want to turn off verbose logging\n\n/**\n * sketching...\n * under construction...\n */\nexport class Subscription_V1\n extends LightWitnessBase_V1<SubscriptionData_V1, SubscriptionRel8ns_V1>\n implements SubscriptionIbGib_V1, SubscriptionWitness {\n\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${Subscription_V1.name}]`;\n\n /**\n * Reference to the local ibgibs service, which is one way at getting at the\n * local user space.\n */\n public metaspace: MetaspaceService | undefined;\n\n /**\n * this is UNDEFINED if we have not yet subscribed.\n *\n * this is only true AFTER we have subscribed.\n *\n * this is FALSE after we have subscribed AND THEN UNSUBSCRIBED.\n */\n private _subscribed: boolean | undefined;\n\n /**\n * this is not !this._subscribed!!!\n *\n * this is only true AFTER we have subscribed and then unsubscribed.\n */\n private _unsubscribed: boolean | undefined;\n\n /**\n * this is the observable\n */\n private _srcObservable: ObservableWitnessAny | undefined;\n\n\n constructor(initialData?: SubscriptionData_V1, initialRel8ns?: SubscriptionRel8ns_V1) {\n super(initialData, initialRel8ns);\n }\n\n protected async initialize(): Promise<void> {\n const lc = `${this.lc}[${this.initialize.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8097612cda5f43e5b38249d057b65b1e)`); }\n await super.initialize();\n\n if (!this.data) { throw new Error(`this.data required (E: 1af73af2d17a48ada42596ad395fd99c)`); }\n this.data.uuid = this.instanceId;\n this.ib = getSubscriptionIb({ data: this.data, classname: 'Subscription_V1' });\n this.gib = await getGib({ ibGib: this });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n *\n * @param arg\n * @returns\n */\n async witness(arg: IbGib_V1): Promise<IbGib_V1 | undefined> {\n const lc = `${this.lc}[${this.witness.name}]`;\n try {\n if (!this._isInitialized) { await this.initialized; }\n const { ib } = arg;\n if (!ib) { throw new Error(`arg.ib required (E: 1fd9aebef07b4bdaacc0cd323c8ddf76)`); }\n if (logalot) { console.log(`${lc} ib: ${ib} (I: 4de7771f477dc5b36933343b694ce223)`); }\n if (ib === SubscriptionCmd.unsubscribe) {\n if (logalot) { console.log(`${lc} routing unsubscribe cmd (I: 5633b86d467af2aa67388abf559a3c23)`); }\n return this.witness_unsubscribe();\n } else if (ib === SubscriptionCmd.unsubscribed) {\n if (logalot) { console.log(`${lc} routing unsubscribed query (I: 6e0ae61d90f1974d76bcdbb47970e723)`); }\n return this.witness_unsubscribed();\n } else if (isObservable({ ibGib: arg })) {\n if (logalot) { console.log(`${lc} routing observerable (I: 165b422cda9ec3052312243dc965cf23)`); }\n return this.witness_observable({ ibGib: arg as ObservableWitnessAny });\n } else {\n throw new Error(`unknown arg. expect unsubscribe/unsubscribed primitive ibgib or Observable ibgib. (E: 132dc7cd8f7c4afc9ec4651e2c559c74)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error) ?? 'unknown error (E: b0bbaab21833404a9420c3d273df7f21)'}`);\n throw error;\n }\n }\n\n private async witness_unsubscribe(): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_unsubscribe.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: a3d549220ef24604956aaa2c66fff09b)`); }\n if (!this._subscribed) {\n console.warn(`${lc} tried to unsubscribe but this._subscribed is ${this._subscribed} (W: cdc94f59447d4011b4b4cc12ef9ec074)`);\n return ROOT; /* <<<< returns early */\n }\n if (this._unsubscribed) {\n console.warn(`{lc} this._unsubscribed already true. (W: fa287d76cec040e0978a8add5c758093)`)\n return ROOT;\n }\n\n if (!this._srcObservable) { throw new Error(`(UNEXPECTED) this._subscribed but this._srcObservable falsy? (E: 83687993b7bea299b4ba2438b530a123)`); }\n\n if (logalot) {\n console.log(`${lc} inspecting srcObservable before src.witness... (I: f15a33d10f1cae3cec6fdbdb32596823)`);\n console.dir(this._srcObservable);\n }\n\n await this._srcObservable.witness(this);\n\n if (logalot) {\n console.log(`${lc} inspecting srcObservable after src.witness... (I: f15a33d10f1cae3cec6fdbdb32596823)`);\n console.dir(this._srcObservable);\n }\n\n // hmm maybe being too picky here with two different 3-state flags.\n this._subscribed = false;\n this._unsubscribed = true;\n delete this._srcObservable;\n\n if (logalot) { console.log(`${lc} this._ (I: 7b1bc418a3d32757772391cad7a49523)`); }\n\n return ROOT;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n private async witness_observable({ ibGib }: { ibGib: ObservableWitnessAny }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_observable.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: faf248f372fc44a7bb0e70492e8284f9)`); }\n if (this._subscribed !== undefined) { throw new Error(`(UNEXPECTED) this._subscribed (${this._subscribed} is not undefined? (E: 09a0e926357676c2c93a173ccbe93923)`); }\n if (this._srcObservable) { throw new Error(`(UNEXPECTED) this subscription isn't subscribed but this._observable is truthy? (E: acdf5198fb2ff3c8b2db95450bd55b23)`); }\n\n // store the observable reference as this subscription's observable\n this._srcObservable = ibGib;\n if (logalot) { console.log(`${lc} this._srcObservable set to ibgib with ib: ${ibGib.ib} (I: 4b81d17243f60dfdcc2163fbb55e9223)`); }\n\n // we are now subscribed\n this._subscribed = true;\n\n // like an ack/ok/void/whatever\n return ROOT;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n private async witness_unsubscribed(): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_unsubscribed.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1beac551253e4c5694b63e0d36d5d5c0)`); }\n if (this._subscribed == undefined) { throw new Error(`subscription never subscribed in the first place (this._subscribed === undefined) (E: b2c1b21a0e876a4908339a976924b923)`); }\n if (this._subscribed && this._unsubscribed) { throw new Error(`(UNEXPECTED) both this._subscribed and this._unsubscribed true (E: a967e49de657a43929a74703c656ad23)`); }\n const result =\n this._unsubscribed === true ?\n TRUE_GIB : // still subscribed, so UNsubscribed is false\n FALSE_GIB; // subscribed is false, so UNsubscribed is true\n if (logalot) { console.log(`${lc} result: ${pretty(result)} (I: b488cf36ce39e006a81d3ad3db5b4a23)`); }\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #region public api\n\n /**\n * unsubscribe a subscriber of an observable via this subscription.\n */\n async unsubscribe(): Promise<void> {\n const lc = `${this.lc}[${this.unsubscribe.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ef7f3f4787a74fcca65d761880f44594)`); }\n const result = await this.witness(Factory_V1.primitive({ ib: SubscriptionCmd.unsubscribe }));\n\n // do we really care about the result other than checking for error?\n if (!result) { throw new Error(`(UNEXPECTED) unsubscribe returned undefined? (E: 7013193490b94b6880f1049c36577d6f)`); }\n\n if (isError({ ibGib: result })) {\n const errorIbGib = result as ErrorIbGib_V1;\n // should we just return the error?\n throw new Error(`${errorIbGib.data!.raw} (E: fca1200dccb14f84968b2462f1b4c29e)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * (async) flag to indicate if a subscription is still active or not.\n *\n * @returns `true` if we have unsubscribed/deactivated this subscription, `false` if this subscription is still active\n */\n async unsubscribed(): Promise<boolean> {\n const lc = `${this.lc}[${this.unsubscribed.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8ee9a93be61647d6aef6a4fa03e96dad)`); }\n const resRaw = await this.witness(Factory_V1.primitive({ ib: SubscriptionCmd.unsubscribed }));\n if (!resRaw) { throw new Error(`(UNEXPECTED) unsubscribe returned undefined? (E: 5051d7ff4a4d4bf7864c520b53f028d5)`); }\n const resUnsubscribed = resRaw.ib === TRUE_GIB.ib;\n if (logalot) { console.log(`${lc} resUnsubscribed: ${resUnsubscribed} (I: b4800166c58d5ba2ca1dccaa53de2323)`); }\n return resUnsubscribed;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion public api\n\n /**\n * validates against common witness qualities.\n *\n * Override this with a call to `super.validateThis` for custom validation\n * for descending witness classes.\n *\n * @returns validation errors common to all subscription witnesses, if any errors exist.\n */\n protected async validateThis(): Promise<string[]> {\n const lc = `${this.lc}[${this.validateThis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!this.data) {\n\n }\n const errors: string[] = [\n // ...await super.validateThis(),\n // ...validateCommonSubscriptionData({ data: this.data }),\n ];\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * builds an arg ibGib.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async argy({\n argData,\n ibMetadata,\n noTimestamp,\n ibGibs,\n }: {\n argData: SubscriptionCmdData,\n ibMetadata?: string,\n noTimestamp?: boolean,\n ibGibs?: IbGib_V1[],\n }): Promise<SubscriptionCmdIbGib> {\n const arg = await argy_<SubscriptionCmdData, SubscriptionCmdRel8ns, SubscriptionCmdIbGib>({\n argData,\n ibMetadata,\n noTimestamp\n });\n\n if (ibGibs) { arg.ibGibs = ibGibs; }\n\n return arg;\n }\n\n /**\n * builds a result ibGib, if indeed a result ibgib is required.\n *\n * This is only useful in witnesses that have more structured\n * inputs/outputs. For those that simply accept any ibgib incoming and\n * return a primitive like ib^gib or whatever, then this is unnecessary.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async resulty({\n resultData,\n ibGibs,\n }: {\n resultData: SubscriptionResultData,\n ibGibs?: IbGib_V1[],\n }): Promise<SubscriptionResultIbGib> {\n const result = await resulty_<SubscriptionResultData, SubscriptionResultIbGib>({\n // ibMetadata: getSubscriptionResultMetadata({space: this}),\n resultData,\n });\n if (ibGibs) { result.ibGibs = ibGibs; }\n return result;\n }\n\n}\n\n/**\n * factory for random Subscription witness.\n *\n * @see {@link DynamicFormFactoryBase}\n */\nexport class Subscription_V1_Factory\n extends DynamicFormFactoryBase<SubscriptionData_V1, SubscriptionRel8ns_V1, Subscription_V1> {\n\n protected lc: string = `[${Subscription_V1_Factory.name}]`;\n\n getName(): string { return Subscription_V1.name; }\n\n async newUp({\n data,\n rel8ns,\n }: {\n data?: SubscriptionData_V1,\n rel8ns?: SubscriptionRel8ns_V1,\n }): Promise<TransformResult<Subscription_V1>> {\n const lc = `${this.lc}[${this.newUp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n data ??= clone(DEFAULT_SUBSCRIPTION_DATA_V1);\n data = data!;\n rel8ns = rel8ns ?? DEFAULT_SUBSCRIPTION_REL8NS_V1 ? clone(DEFAULT_SUBSCRIPTION_REL8NS_V1) : undefined;\n data.uuid ||= await getUUID();\n let { classname } = data;\n\n const ib = getSubscriptionIb({ data });\n\n // subscription is a constant, so we dont need to create a\n // dependency graph or timeline or anything like that. it's just a\n // stone.\n const subscriptionIbGibDto =\n await constantIbGib<SubscriptionData_V1, SubscriptionRel8ns_V1>({\n parentPrimitiveIb: `witness ${classname}`,\n ib, data, rel8ns,\n }) as SubscriptionIbGib_V1;\n\n // replace the newIbGib which is just ib,gib,data,rel8ns with loaded\n // witness class (that has the witness function on it)\n const witnessIbGib = new Subscription_V1(undefined, undefined);\n await witnessIbGib.loadIbGibDto(subscriptionIbGibDto);\n if (logalot) { console.log(`${lc} witnessDto: ${pretty(subscriptionIbGibDto)} (I: 5e41337176d1441f9a5c7b43664d43ef)`); }\n\n return { newIbGib: witnessIbGib };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg({ error })}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async witnessToForm({ witness }: { witness: Subscription_V1; }): Promise<DynamicForm> {\n const lc = `${this.lc}[${this.witnessToForm.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n let { data } = witness;\n if (!data) { throw new Error(`(UNEXPECTED) witness.data falsy? (E: ef44497ff97a4e5bac004d52c4ff40eb)`); }\n if (logalot) { console.log(`${lc} data: ${pretty(data)} (I: c3f4c3d85386461aaefbe33524ff9cbd)`); }\n // be careful of order here because of TS type inference\n const idPool = await getIdPool({ n: 100 });\n const form = new SubscriptionFormBuilder()\n .with({ idPool })\n .name({ of: data.name!, required: false, })\n .description({ of: data.description ?? DEFAULT_DESCRIPTION_SUBSCRIPTION })\n .and<SubscriptionFormBuilder>()\n .and<DynamicFormBuilder>()\n .uuid({ of: data.uuid!, required: true })\n .classname({ of: data.classname! })\n .and<WitnessFormBuilder>()\n .commonWitnessFields({ data })\n .outputForm({\n formName: 'form',\n label: 'subscription',\n });\n return Promise.resolve(form);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg({ error })}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async formToWitness({ form }: { form: DynamicForm; }): Promise<TransformResult<Subscription_V1>> {\n let data: SubscriptionData_V1 = clone(DEFAULT_SUBSCRIPTION_DATA_V1);\n this.patchDataFromItems({ data, items: form.items, pathDelimiter: DEFAULT_DATA_PATH_DELIMITER });\n let resWitnessIbGib = await this.newUp({ data });\n return resWitnessIbGib;\n }\n\n}\n", "/*\n * @module subscription helper/util/etc. functions\n *\n * this is where you will find helper functions like those that generate\n * and parse ibs for subscription.\n */\n\n// import * as pathUtils from 'path';\n// import { statSync } from 'node:fs';\n// import { readFile, } from 'node:fs/promises';\n// import * as readline from 'node:readline/promises';\n// import { stdin, stdout } from 'node:process'; // decide if use this or not\n\nimport {\n extractErrorMsg, delay, getSaferSubstring,\n getTimestampInTicks, getUUID, pretty,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { UUID_REGEXP, CLASSNAME_REGEXP, } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { validateIbGibIntrinsically, } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport { WitnessFormBuilder } from '../../../witness/witness-form-builder.mjs';\n// import { IbGibSubscriptionAny } from './subscription-v1.mjs';\nimport {\n SubscriptionData_V1, SubscriptionRel8ns_V1, SubscriptionIbGib_V1, SubscriptionWitness,\n} from './subscription-types.mjs';\nimport { SUBSCRIPTION_ATOM, SUBSCRIPTION_NAME_REGEXP, } from './subscription-constants.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { Subscription_V1, Subscription_V1_Factory } from './subscription-v1.mjs';\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport function validateCommonSubscriptionData({\n data,\n}: {\n data?: SubscriptionData_V1,\n}): string[] {\n const lc = `[${validateCommonSubscriptionData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!data) { throw new Error(`Subscription Data required (E: 6d1c97931dcab8ea9f3e9b32c794b90c)`); }\n const errors: string[] = [];\n const {\n name, uuid, classname,\n } =\n data;\n\n if (name) {\n if (!name.match(SUBSCRIPTION_NAME_REGEXP)) {\n errors.push(`name must match regexp: ${SUBSCRIPTION_NAME_REGEXP} (E: 21bf77e398d47e9d035376510505eda2)`);\n }\n } else {\n errors.push(`name required.`);\n }\n\n if (uuid) {\n if (!uuid.match(UUID_REGEXP)) {\n errors.push(`uuid must match regexp: ${UUID_REGEXP} (E: e53fd08ae69e945b37ed895b864b6bd7)`);\n }\n } else {\n errors.push(`uuid required.`);\n }\n\n if (classname) {\n if (!classname.match(CLASSNAME_REGEXP)) {\n errors.push(`classname must match regexp: ${CLASSNAME_REGEXP}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateCommonSubscriptionIbGib({\n ibGib,\n}: {\n ibGib: SubscriptionIbGib_V1,\n}): Promise<string[] | undefined> {\n const lc = `[${validateCommonSubscriptionIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 53696a50efff60fd86a2f431dae6ac67)`); }\n const intrinsicErrors: string[] = await validateIbGibIntrinsically({ ibGib }) ?? [];\n\n if (!ibGib.data) { throw new Error(`ibGib.data required (E: 5bae607c41ed4de40ec333a40673bdb8)`); }\n const ibErrors: string[] = [];\n let { SubscriptionClassname, SubscriptionName, SubscriptionId } =\n parseSubscriptionIb({ ib: ibGib.ib });\n if (!SubscriptionClassname) { ibErrors.push(`SubscriptionClassname required (E: 029f7a2405c4b7aa1f52711586f8ebfd)`); }\n if (!SubscriptionName) { ibErrors.push(`SubscriptionName required (E: e68cbc6f3183169c35117184f610573e)`); }\n if (!SubscriptionId) { ibErrors.push(`SubscriptionId required (E: 0516442854be7ec32f5928b4cf2697f7)`); }\n\n const dataErrors = validateCommonSubscriptionData({ data: ibGib.data });\n\n let result = [...(intrinsicErrors ?? []), ...(ibErrors ?? []), ...(dataErrors ?? [])];\n if (result.length > 0) {\n return result;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getSubscriptionIb({\n data,\n classname,\n}: {\n data: SubscriptionData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getSubscriptionIb.name}]`;\n try {\n const validationErrors = validateCommonSubscriptionData({ data });\n if (validationErrors.length > 0) { throw new Error(`invalid Subscription data: ${validationErrors} (E: fd6b0b32d8f6c4b97eebd489cdb07a4a)`); }\n if (classname) {\n if (data.classname && data.classname !== classname) { throw new Error(`classname does not match data.classname (E: 354285a56a20b9b65b06abfcd9f2e621)`); }\n } else {\n classname = data.classname;\n if (!classname) { throw new Error(`classname required (E: 040c1fd71853fa7874146999afb355c3)`); }\n }\n\n // ad hoc validation here. should centralize witness classname validation\n\n const { uuid } = data;\n // uuid is instanceId (atow 11/2023)\n return `witness ${SUBSCRIPTION_ATOM} ${classname} ${uuid}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Current schema is 'witness [SUBSCRIPTION_ATOM] [classname] [SubscriptionName] [SubscriptionId]'\n *\n * NOTE this is space-delimited\n */\nexport function parseSubscriptionIb({\n ib,\n}: {\n ib: Ib,\n}): {\n SubscriptionClassname: string,\n SubscriptionName: string,\n SubscriptionId: string,\n} {\n const lc = `[${parseSubscriptionIb.name}]`;\n try {\n if (!ib) { throw new Error(`Subscription ib required (E: 84156af64e73d479220a36f247466659)`); }\n\n const pieces = ib.split(' ');\n\n return {\n SubscriptionClassname: pieces[2],\n SubscriptionName: pieces[3],\n SubscriptionId: pieces[4],\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport class SubscriptionFormBuilder extends WitnessFormBuilder {\n protected lc: string = `[${SubscriptionFormBuilder.name}]`;\n\n constructor() {\n super();\n this.what = 'subscription';\n }\n\n // exampleSetting({\n // of,\n // required,\n // }: {\n // of: string,\n // required?: boolean,\n // }): SubscriptionFormBuilder {\n // this.addItem({\n // // Subscription.data.exampleSetting\n // name: \"exampleSetting\",\n // description: `example description`,\n // label: \"Example Label\",\n // regexp: EXAMPLE_REGEXP,\n // regexpErrorMsg: EXAMPLE_REGEXP_DESC,\n // dataType: 'textarea',\n // value: of,\n // required,\n // });\n // return this;\n // }\n\n}\n\nexport function isSubscription({\n ibGib,\n}: {\n ibGib: IbGib_V1 | undefined,\n}): boolean {\n const lc = `[${isSubscription.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 43df7e7f61f25e65662ce8aa5a105a23)`); }\n if (!ibGib) { return false; }\n let sub = ibGib as SubscriptionWitness;\n return typeof sub.witness === 'function' &&\n typeof sub.unsubscribe === 'function' &&\n typeof sub.unsubscribed === 'function';\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// #region sugar\n\n/**\n * Uses {@link Subscription_V1_Factory} to new up a blank subscription.\n * @returns subscription\n */\nexport async function newupSubscription(): Promise<Subscription_V1> {\n const subscriptionFactory = new Subscription_V1_Factory();\n return (await subscriptionFactory.newUp({})).newIbGib;\n}\n\n// #endregion sugar\n", "\nexport const OBSERVABLE_EVENT_ATOM = 'observable_event';\n", "/**\n * @module observable-event-helper helper functions, utils, etc.\n */\n\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../../../../core-constants.mjs\";\nimport { ObservableEventData_V1, ObservableEventIbGib_V1, ObservableEventType } from \"./observable-event-types.mjs\";\nimport { constantIbGib } from \"../../../other/ibgib-helper.mjs\";\nimport { OBSERVABLE_EVENT_ATOM } from \"./observable-event-constants.mjs\";\nimport { extractErrorMsg, getUUID } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { ObservableData_V1, ObservableWitness } from \"../observable-types.mjs\";\nimport { Ib } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { UUID_REGEXP } from \"@ibgib/helper-gib/dist/constants.mjs\";\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT; // change this when you want to turn off verbose logging\n\nexport async function getObservableEventIbGib<TIbGibIn_ie_Payload extends IbGib_V1>({\n eventType,\n srcObservable,\n payload,\n}: {\n eventType: ObservableEventType,\n srcObservable: ObservableWitness<TIbGibIn_ie_Payload>,\n payload: TIbGibIn_ie_Payload | undefined,\n}): Promise<ObservableEventIbGib_V1<TIbGibIn_ie_Payload>> {\n const lc = `[${getObservableEventIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e2290f2f46d1993d6893a24c19100823)`); }\n\n // validate\n if (!srcObservable) { throw new Error(`srcObservable required (E: 3470a97bbf3802cbc8dd64339f5ef623)`); }\n if (!srcObservable.data) { throw new Error(`srcObservable.data required (E: df1786585ba849c08e7f4f1fddd30a31)`); }\n if (!srcObservable.data.uuid) { throw new Error(`srcObservable.data.uuid required (E: 173a1a53f274bc1cef879bad2288ca23)`); }\n if (!(srcObservable.data.uuid as string).match(UUID_REGEXP)) { throw new Error(`valid srcObservable.data.uuid required. must pass UUID_REGEXP: ${UUID_REGEXP.source} (E: 10f4bd1863f18250cc79cd65221da223)`); }\n\n const data: ObservableEventData_V1 = {\n uuid: await getUUID(),\n eventType,\n srcObservableId: srcObservable.data.uuid,\n \"@srcObservableAddr\": getIbGibAddr({ ibGib: srcObservable }),\n \"@payloadAddr\": getIbGibAddr({ ibGib: payload }),\n };\n\n const ibGib = await constantIbGib({\n parentPrimitiveIb: OBSERVABLE_EVENT_ATOM,\n ib: getObservableEventIb({ data }),\n data,\n }) as ObservableEventIbGib_V1<TIbGibIn_ie_Payload>;\n\n return ibGib;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport function getObservableEventIb({\n data,\n classname,\n}: {\n data: ObservableData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getObservableEventIb.name}]`;\n try {\n if (classname) {\n if (data.classname && data.classname !== classname) { throw new Error(`classname does not match data.classname (E: 523aabc53fb944789202a5f468abd338)`); }\n } else {\n classname = data.classname;\n if (!classname) { throw new Error(`classname required (E: d4401ea682894c5fa824b38d4989aa76)`); }\n }\n\n if (!data.uuid) { throw new Error(`data.uuid required (E: 204cc7c20efd8a55263cdea8b1223e23)`); }\n\n return `${OBSERVABLE_EVENT_ATOM} ${classname} ${data.uuid}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Current schema is '[OBSERVABLE_EVENT_ATOM] [classname] [ObservableEventId]'\n *\n * NOTE this is space-delimited\n */\nexport function parseObservableEventIb({\n ib,\n}: {\n ib: Ib,\n}): {\n ObservableEventClassname: string,\n ObservableEventId: string,\n} {\n const lc = `[${parseObservableEventIb.name}]`;\n try {\n if (!ib) { throw new Error(`ObservableEvent ib required (E: 6cd1184d52284912916d6f972d375113)`); }\n\n const pieces = ib.split(' ');\n\n return {\n ObservableEventClassname: pieces[1],\n ObservableEventId: pieces[2],\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n", "/**\n * @module ObservableBase_V1 witness class\n *\n */\n\nimport {\n delay,\n extractErrorMsg,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGib_V1, } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';\nimport { argy_, isArg, isCommand, isWitness, resulty_ } from '../../../witness/witness-helper.mjs';\nimport {\n ObservableData_V1, ObservableRel8ns_V1, ObservableIbGib_V1,\n ObservableCmd,\n ObservableResultData, ObservableResultIbGib,\n OBSERVABLE_CMD_VALUES,\n ObservableWitness,\n} from './observable-types.mjs';\nimport { LightWitnessBase_V1 } from '../../../witness/light-witness-base-v1.mjs';\nimport { WitnessAny } from '../../../witness/witness-types.mjs';\nimport { SubscriptionIbGib_V1, SubscriptionWitness } from '../subscription/subscription-types.mjs';\nimport { isObserver } from '../subject/subject-helper.mjs';\nimport { ObserverWitness, } from '../observer/observer-types.mjs';\nimport { isSubscription, newupSubscription } from '../subscription/subscription-helper.mjs';\nimport { WitnessCmdData, WitnessCmdIbGib, WitnessCmdRel8ns } from '../../../witness/witness-cmd/witness-cmd-types.mjs';\nimport { getObservableEventIbGib } from './observable-event/observable-event-helper.mjs';\nimport { ObservableEventType } from './observable-event/observable-event-types.mjs';\nimport { ErrorIbGib_V1 } from '../../error/error-types.mjs';\n\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT; // change this when you want to turn off verbose logging\n\n/**\n * sketching...\n * under construction...\n */\nexport abstract class ObservableBase_V1<\n TIbGibIn_ie_Payload extends IbGib_V1 = IbGib_V1,\n TIbGibOut_ie_ProbablyDontCare extends IbGib_V1 = IbGib_V1,\n TCmd = any, TCmdModifiers = any,\n TCmdData extends WitnessCmdData<TCmd, TCmdModifiers> = WitnessCmdData<TCmd, TCmdModifiers>,\n TCmdRel8ns extends WitnessCmdRel8ns = WitnessCmdRel8ns,\n TCmdIbGib extends WitnessCmdIbGib<IbGib_V1, TCmd, TCmdModifiers, TCmdData, TCmdRel8ns> = WitnessCmdIbGib<IbGib_V1, TCmd, TCmdModifiers, TCmdData, TCmdRel8ns>,\n TData extends ObservableData_V1 = ObservableData_V1,\n TRel8ns extends ObservableRel8ns_V1 = ObservableRel8ns_V1\n>\n extends LightWitnessBase_V1<TData, TRel8ns>\n implements ObservableIbGib_V1, ObservableWitness<TIbGibIn_ie_Payload> {\n\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${ObservableBase_V1.name}]`;\n\n /**\n * Reference to the local ibgibs service, which is one way at getting at the\n * local user space.\n */\n public metaspace: MetaspaceService | undefined;\n\n protected _subscribers: { [subscriptionId: string]: [SubscriptionWitness, ObserverWitness<TIbGibIn_ie_Payload> | WitnessAny] } = {};\n\n protected _isComplete: boolean = false;\n\n /**\n * this is used for {@link SubjectData_V1.replay}\n */\n protected _pastPayloads: TIbGibIn_ie_Payload[] = [];\n /**\n * if observable errors out, this should be the stored error.\n */\n protected _pastError: ErrorIbGib_V1 | Error | string | undefined;\n\n // #region public api properties\n\n get isCompleteOrErrored(): boolean {\n return this._isComplete || !!this._pastError;\n }\n get isComplete(): boolean { return this._isComplete; }\n get isErrored(): boolean { return !!this._pastError; }\n\n // #endregion public api properties\n\n constructor(initialData?: TData, initialRel8ns?: TRel8ns) {\n super(initialData, initialRel8ns);\n }\n\n /**\n * The observable's primary function is to accept subscribers\n * who wish to observe the stream of ibgibs this observable creates.\n *\n * So there are two ways to subscribe:\n *\n * ## 1. Use an ObservableCmd (via this.argy(...) for convenience)\n *\n * @see {@link subscribe}\n *\n * ## 2. Use any ol' Witness IbGib\n\n * @see {@link witness_otherWitness}\n *\n * @param arg\n * @returns\n *\n * @see {@link argy}\n */\n async witness(arg: IbGib_V1): Promise<IbGib_V1 | undefined> {\n const lc = `${this.lc}[${this.witness.name}]`;\n try {\n if (!this._isInitialized) { await this.initialized; }\n const { ib } = arg;\n if (!ib) { throw new Error(`arg.ib required (E: 87659d093b82436ce2f7a87e402a5423)`); }\n if (isCommand({ ibGib: arg })) {\n return this.witness_cmd({ arg: arg as TCmdIbGib });\n } else if (isWitness({ ibGib: arg })) {\n return this.witness_otherWitness({ arg: arg as WitnessAny });\n } else {\n throw new Error(`unknown arg. expect observable cmd or ibgib witness (E: dc2667cffac5b8d7b1bf2ea737c81a23)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error) ?? 'unknown error (E: 3e22bea4c7fb4668bf13d7146b927869)'}`);\n throw error;\n }\n }\n\n // #region witness sub-functions\n\n /**\n * default implementation here subscribes the witness.\n *\n * override this for custom handling cmds.\n *\n * @returns idk, an ibgib\n */\n protected async witness_cmd({\n arg,\n }: {\n arg: TCmdIbGib,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_cmd.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 69257fac8328b9de9755fdd237b92723)`); }\n if (arg.data!.cmd === ObservableCmd.subscribe) {\n return this.witness_subscribe_cmd({ ibGib: arg as TCmdIbGib });\n } else {\n throw new Error(`unknown command. must be of type ObservableCmd (${OBSERVABLE_CMD_VALUES}) (E: 5910e5cbafead25ea2917a65a3fc4123)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async witness_otherWitness({\n arg,\n }: {\n arg: WitnessAny,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_otherWitness.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 871d0b7a2bef4596bad430f1cbacde02)`); }\n if (isSubscription({ ibGib: arg })) {\n return this.witness_subscriptionIbGib({ arg: arg as SubscriptionIbGib_V1 });\n } else {\n return this.witness_subscribe_nonCmdWitness({ arg });\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async witness_subscriptionIbGib({\n arg,\n }: {\n arg: SubscriptionIbGib_V1,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_subscriptionIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4ac764776ef7e3f9074eb95a999ba423)`); }\n if (!arg.data) { throw new Error(`arg.data required (E: 764ae772727ceba95a18140fdd938323)`); }\n const key = this.getSubscriberKey({ subscription: arg });\n const [subscription, _observer] = this._subscribers[key];\n // will the stored subscription always be the same instance as the arg?\n if (arg === subscription) {\n delete this._subscribers[key];\n } else {\n throw new Error(`(UNEXPECTED) arg and subscription are two different instances? (E: aab5ef9bdc92abb9e816e2c443ab5723)`);\n }\n return ROOT;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async replayPastPayloads({\n observer,\n subscription,\n }: {\n observer: ObserverWitness<TIbGibIn_ie_Payload>,\n subscription: SubscriptionWitness,\n }): Promise<void> {\n const lc = `${this.lc}[${this.replayPastPayloads.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b3c8f9c76a4af030cf52fdcf01c3fd23)`); }\n\n // we want to be able to abort replay if the subscription is\n // unsubscribed during this execution. (imagine a long list to\n // replay and the subscriber cancels subscription after they found\n // out what they needed).\n\n const subscriberKey = this.getSubscriberKey({ subscription });\n const fnStillSubscribed = () => {\n return !!this._subscribers[subscriberKey];\n };\n\n // we cannot do a for loop because the pastPayloads may change\n // during execution. so we will do manual \"jit\" checking for the\n // index.\n let i = -1;\n let keepGoing = true;\n do {\n i++;\n if (i < this._pastPayloads.length) {\n // stillSubscribed = await subscription.unsubscribed();\n if (!fnStillSubscribed()) {\n if (logalot) { console.log(`${lc} subscription canceled before past payloads dispatch completed. (I: f1778f868446a518030d1cf7800c8a23)`); }\n return; /* <<<< returns early */\n }\n try {\n const payload = this._pastPayloads[i];\n await observer.next(payload);\n } catch (error) {\n console.error(`${lc} observer errored on payload (i: ${i}). aborting replay (E: 1d7efc7c48e1491da4317ef333031077)`)\n return; /* <<<< returns early */\n }\n } else {\n keepGoing = false;\n }\n } while (keepGoing);\n\n if (this.isErrored && observer.error && fnStillSubscribed()) {\n try {\n await observer.error(this._pastError!);\n } catch (error) {\n console.error(`${lc} observer.error(this._pastError) errored itself (E: 18310e5e032345e7bdc3f2479807866c)`);\n }\n } else if (this.isComplete && observer.complete && fnStillSubscribed()) {\n try {\n await observer.complete();\n } catch (error) {\n console.error(`${lc} observer.complete errored (E: d9d027f5520f4d7eadfc669d66b5b550)`);\n }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n protected async witness_subscribe_cmd({\n ibGib,\n }: {\n ibGib: TCmdIbGib,\n }): Promise<SubscriptionWitness> {\n const lc = `${this.lc}[${this.witness_subscribe_cmd.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0c4c75c3fae297af6449c1048ce55423)`); }\n\n // validate arg and extract observer from it\n if ((ibGib.ibGibs ?? []).length !== 1) { throw new Error(`ibGib.ibGibs required. should contain one ObserverWitness (E: 3ed99b32e22284573c497df788a9f923)`); }\n const observer = ibGib.ibGibs![0] as ObserverWitness<TIbGibIn_ie_Payload>;\n\n // create the subscription\n const subscription = await newupSubscription();\n if (logalot) { console.log(`${lc} subscription created (I: 89ccd97803c66292f9d7334e1e2de523)`); }\n await subscription.witness(this);\n await subscription.initialized;\n if (logalot) { console.log(`${lc} subscription initialized (after witnessing this observable as its src). (I: 3021483402b21c4df64a9173bd223a23)`); }\n\n // store subscription with observer for unsubscribe purposes BEFORE spinning off\n // replayPastPayloads, because that relies on cancellation detection of looking\n // at this key\n this._subscribers[this.getSubscriberKey({ subscription })] = [subscription, observer];\n if (logalot) { console.log(`${lc} stored subscriber (subscription, observer) (I: fb09660d885e33b80188dd0386ffc723)`); }\n\n // spin off dispatch of previous payloads if applicable AFTER adding\n // subscriber to this._subscribers.\n if (this.data!.replay && this._pastPayloads.length > 0) {\n // SPINS OFF!!\n this.replayPastPayloads({ observer, subscription });\n }\n\n // return it!\n return subscription;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * we have been given a witness ibGib that is not a command. by default, an\n * observable will subscribe a witness, and when a value comes down the pipe\n * the witness will have its `witness` fn called a la a visitor pattern. If\n * an error occurs, it will be propagated. I'm not sure how to do the\n * `observer.complete` analog.\n * @param arg ibgib object with `witness` function\n */\n protected async witness_subscribe_nonCmdWitness({ arg }: { arg: WitnessAny }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_subscribe_nonCmdWitness.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d9571dfcab4247d594c838233971886a)`); }\n throw new Error(`not impl (E: 76219cf238ba4f849480bd7c82eefab9)`);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion witness sub-functions\n\n // #region public api\n\n /**\n * subscribes the given `observer` to this observable's stream.\n *\n * ## notes\n *\n * * The `observer` can be any ibgib witness (not specifically expose the\n * {@link ObserverWitness} contract), but that witness will have to be\n * able to deal with this observable's outputs via that witness ibGib's\n * `witness` function (visitor pattern).\n * * this is a wrapper that internally produces an ObservableCmd\n *\n * @param observer\n *\n * @returns subscription used for unsubscribing\n */\n async subscribe(observer: WitnessAny | ObserverWitness<TIbGibIn_ie_Payload>): Promise<SubscriptionWitness> {\n const lc = `${this.lc}[${this.subscribe.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0dec9a06c562711e19482d45a7075e23)`); }\n let resSubscription: SubscriptionWitness;\n if (isObserver({ ibGib: observer })) {\n // witness with Observer shape\n const arg = await this.argy({\n argData: {\n cmd: ObservableCmd.subscribe,\n ibGibAddrs: [getIbGibAddr({ ibGib: observer })],\n } as TCmdData, // I'm struggling to think of a descending TCmdData 'subscribe' that has other properties\n ibGibs: [observer]\n });\n resSubscription = await this.witness(arg) as SubscriptionWitness;\n } else {\n // plain ol' witness (without a `next` fn atow 11/2023)\n resSubscription = await this.witness(observer) as SubscriptionWitness;\n }\n if (!isSubscription({ ibGib: resSubscription })) { throw new Error(`(UNEXPECTED) resSubscription is not a SubscriptionWitness? (E: c29bec4e3a48d6f1299143399ac55a23)`); }\n return resSubscription;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion public api\n\n // #region helpers\n\n private getSubscriberKey({\n subscription,\n }: {\n subscription: SubscriptionIbGib_V1\n }): string {\n if (subscription.data?.uuid) {\n return subscription.data.uuid;\n } else {\n throw new Error(`(UNEXPECTED) subscription.data.uuid falsy? (E: 8d078e6f8155f7567fd9378557e91823)`);\n }\n\n }\n\n protected async dispatchToEachSubscriber({\n payload,\n fnForObserver,\n observableEventType,\n }: {\n /**\n * payload to dispatch\n */\n payload: TIbGibIn_ie_Payload | undefined,\n /**\n * fn to execute dispatch for each observer subscriber.\n *\n * each subscriber is either an observer or a plain jane witness. if\n * it's a plain witness, then it's easy - we just dispatch the payload\n * to the `subscriber.witness` function. If it's an observer though,\n * we need to decide which function to do: `next`, `error`, `complete`.\n */\n fnForObserver: (observer: ObserverWitness<TIbGibIn_ie_Payload>, payload: TIbGibIn_ie_Payload | undefined) => Promise<void>,\n /**\n * this type is used for dispatching to bare witness subscribers (i.e.\n * non-observer interface witnesses).\n */\n observableEventType: ObservableEventType,\n }): Promise<void> {\n const lc = `${this.lc}[${this.dispatchToEachSubscriber.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0b990ce892f689d14458565717e66a23)`); }\n\n // dispatch to subscribers (serially)\n const subscriberTuples = Object.values(this._subscribers);\n for (let i = 0; i < subscriberTuples.length; i++) {\n const [subscription, observerOrWitness] = subscriberTuples[i];\n\n // depends on if subscriber is observer or plain witness...\n if (isObserver({ ibGib: observerOrWitness })) {\n // subscriber uses observer interface\n const observer = observerOrWitness as ObserverWitness<TIbGibIn_ie_Payload>;\n await fnForObserver(observer, payload);\n if (observer.complete) {\n // we remove subscribers on unsubscribe, but just in case we\n // will double-check here if we are still subscribed\n const unsubscribed = await subscription.unsubscribed();\n if (!unsubscribed) {\n // dispatch to observer's via its `next` fn\n await observer.complete();\n } else {\n console.warn(`${lc} (UNEXPECTED) subscriber reference still held but is unsubscribed? skipping for now (i.e. won't remove subscriber) in case that code is in yielded execution and just hasn't gotten around to it with event loop (but that would be weird). (W: 1d98f35d2fdd4345954c947265d9fb85)`)\n }\n } else {\n // no error handler for this observer\n if (logalot) { console.log(`${lc} no error handler for observer. skipping. (I: 6a8a52c2012c464790eb406d2ae0383f)`); }\n }\n } else {\n // subscriber is an ibGib witness (not an observer interface)\n // so wrap the payload into an event and pass to\n // `subscriber.witness` fn\n const observableEventWrapper = await getObservableEventIbGib({\n eventType: observableEventType,\n srcObservable: this,\n payload,\n });\n await observerOrWitness.witness(observableEventWrapper);\n }\n }\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * validates against common witness qualities.\n *\n * Override this with a call to `super.validateThis` for custom validation\n * for descending witness classes.\n *\n * @returns validation errors common to all observable witnesses, if any errors exist.\n */\n protected async validateThis(): Promise<string[]> {\n const lc = `${this.lc}[${this.validateThis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!this.data) {\n\n }\n const errors: string[] = [\n // ...await super.validateThis(),\n // ...validateCommonObservableData({ data: this.data }),\n ];\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * builds an arg ibGib.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async argy({\n argData,\n ibMetadata,\n noTimestamp,\n ibGibs,\n }: {\n argData: TCmdData,\n ibMetadata?: string,\n noTimestamp?: boolean,\n ibGibs?: IbGib_V1[],\n }): Promise<TCmdIbGib> {\n const arg = await argy_<TCmdData, TCmdRel8ns, TCmdIbGib>({\n argData,\n ibMetadata,\n noTimestamp\n });\n\n if (ibGibs) { arg.ibGibs = ibGibs; }\n\n return arg;\n }\n\n /**\n * builds a result ibGib, if indeed a result ibgib is required.\n *\n * This is only useful in witnesses that have more structured\n * inputs/outputs. For those that simply accept any ibgib incoming and\n * return a primitive like ib^gib or whatever, then this is unnecessary.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async resulty({\n resultData,\n ibGibs,\n }: {\n resultData: ObservableResultData,\n ibGibs?: IbGib_V1[],\n }): Promise<ObservableResultIbGib> {\n const result = await resulty_<ObservableResultData, ObservableResultIbGib>({\n // ibMetadata: getObservableResultMetadata({space: this}),\n resultData,\n });\n if (ibGibs) { result.ibGibs = ibGibs; }\n return result;\n }\n\n // #endregion helpers\n\n}\n", "/*\n * @module Subject_V1 witness class\n *\n * this is where you will find the witness class that contains behavior\n * for the Subject ibgib.\n *\n * A observable can do two things from the caller's side:\n *\n * 1. unsubscribe\n * 2. give a boolean on whether it has been unsubscribed or not\n *\n * A observable is created from a call to subscribe on an observable. Since\n * the observable is also a witness, we can have this observable visit the\n * observable via `observable.witness(observable)`. IOW, the observable\n * witness ibgib is the argument to `witness` function.\n *\n * The observable will know that if a observable visits it, then the\n * observable needs to release/unsubscribe that observable.\n *\n * So since this is a light witness, we can just have two primitives be the\n * incoming argument ibgibs: unsubscribe^gib and unsubscribed^gib.\n */\n\nimport {\n extractErrorMsg, delay, getSaferSubstring,\n getTimestampInTicks, getUUID, pretty, clone, getIdPool,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { DEFAULT_DATA_PATH_DELIMITER } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { IbGibData_V1, IbGibRel8ns_V1, IbGib_V1, } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { TransformResult } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { ROOT } from '@ibgib/ts-gib/dist/V1/constants.mjs';\n\nimport { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';\nimport { argy_, isArg, isCommand, resulty_ } from '../../../witness/witness-helper.mjs';\nimport { getErrorIbGib, isError } from '../../error/error-helper.mjs';\nimport { DynamicFormBuilder } from '../../form/form-helper.mjs';\nimport { WitnessFormBuilder } from '../../../witness/witness-form-builder.mjs';\nimport { DynamicFormFactoryBase } from '../../../witness/factory/dynamic-form-factory-base.mjs';\nimport { DynamicForm } from '../../form/form-items.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport {\n SubjectData_V1, SubjectRel8ns_V1, SubjectIbGib_V1,\n SubjectCmd, SubjectCmdData, SubjectCmdRel8ns, SubjectCmdIbGib,\n SubjectResultData, SubjectResultRel8ns, SubjectResultIbGib,\n SubjectAddlMetadata,\n DEFAULT_SUBJECT_DATA_V1,\n DEFAULT_SUBJECT_REL8NS_V1,\n SubjectWitness,\n SubjectCmdModifier,\n} from './subject-types.mjs';\nimport { SubjectFormBuilder, getSubjectIb, isObserver } from './subject-helper.mjs';\nimport { DEFAULT_DESCRIPTION_SUBJECT, } from './subject-constants.mjs';\nimport { WitnessAny, } from '../../../witness/witness-types.mjs';\nimport { ErrorIbGib_V1 } from '../../error/error-types.mjs';\nimport { ObservableCmd, ObservableWitness, } from '../observable/observable-types.mjs';\nimport { ObserverWitness, Observer } from '../observer/observer-types.mjs';\nimport { constantIbGib } from '../../other/ibgib-helper.mjs';\nimport { SubscriptionWitness } from '../subscription/subscription-types.mjs';\nimport { ObservableBase_V1 } from '../observable/observable-base-v1.mjs';\n\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT; // change this when you want to turn off verbose logging\n\n/**\n * sketching...\n * under construction...\n */\nexport class Subject_V1<\n TIbGibIn_ie_Payload extends IbGib_V1 = IbGib_V1,\n TIbGibOut_ie_ProbablyDontCare extends IbGib_V1 = IbGib_V1\n> extends ObservableBase_V1<\n TIbGibIn_ie_Payload,\n TIbGibOut_ie_ProbablyDontCare,\n SubjectCmd, SubjectCmdModifier,\n SubjectCmdData, SubjectCmdRel8ns, SubjectCmdIbGib,\n SubjectData_V1, SubjectRel8ns_V1\n> implements SubjectIbGib_V1, SubjectWitness<TIbGibIn_ie_Payload, TIbGibOut_ie_ProbablyDontCare> {\n /**\n * Log context for convenience with logging. (Ignore if you don't want to use this.)\n */\n protected lc: string = `[${Subject_V1.name}]`;\n\n // /**\n // * Reference to the local ibgibs service, which is one way at getting at the\n // * local user space.\n // */\n // public metaspace: MetaspaceService | undefined;\n\n constructor(initialData?: SubjectData_V1, initialRel8ns?: SubjectRel8ns_V1) {\n super(initialData, initialRel8ns);\n }\n\n // #region public api methods\n\n asObservable(): ObservableWitness<TIbGibIn_ie_Payload, TIbGibOut_ie_ProbablyDontCare> {\n return this as ObservableWitness<TIbGibIn_ie_Payload, TIbGibOut_ie_ProbablyDontCare>;\n }\n async subscribe(observer: WitnessAny | ObserverWitness<TIbGibIn_ie_Payload>): Promise<SubscriptionWitness> {\n const lc = `${this.lc}[${this.subscribe.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8e47b752314870ec78eb14342621f723)`); }\n const arg = await this.argy({\n argData: {\n cmd: SubjectCmd.subscribe,\n ibGibAddrs: [getIbGibAddr({ ibGib: observer })],\n },\n ibGibs: [observer],\n });\n const subscription = await this.witness(arg) as SubscriptionWitness;\n return subscription;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n async next(ibGib: TIbGibIn_ie_Payload): Promise<void> {\n const lc = `${this.lc}[${this.next.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b30363827c56450ca918c69aa15b0046)`); }\n const arg = await this.argy({\n argData: {\n cmd: SubjectCmd.next,\n ibGibAddrs: [getIbGibAddr({ ibGib })],\n },\n ibGibs: [ibGib],\n });\n\n await this.witness(arg); // ignores return value\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n async error(error: string | Error | ErrorIbGib_V1): Promise<void> {\n const lc = `${this.lc}[${this.error.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 7fcc30e3763c429ea8b212491ad9455a)`); }\n\n // wrap raw Error if necessary into an ErrorIbGib_V1\n let errorIbGib: ErrorIbGib_V1;\n if (typeof error === 'string') {\n errorIbGib = await getErrorIbGib({ rawMsg: error });\n } else if (error instanceof Error || typeof (error as any).message === 'string') {\n errorIbGib = await getErrorIbGib({ rawMsg: extractErrorMsg(error) });\n } else if (!!(error as IbGib_V1).ib && isError({ ibGib: (error as IbGib_V1) })) {\n errorIbGib = error as ErrorIbGib_V1;\n } else {\n throw new Error(`unknown error type. shold either be ErrorIbGib_V1 or an Error instance or have error.message string property. (E: 2cfcab85439c3c845bfe18e8ecde3523)`);\n }\n\n // build the arg\n const arg = await this.argy({\n argData: {\n cmd: SubjectCmd.error,\n ibGibAddrs: [getIbGibAddr({ ibGib: errorIbGib })],\n },\n ibGibs: [errorIbGib],\n });\n\n // do it\n await this.witness(arg); // ignores return value\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n async complete(): Promise<void> {\n const lc = `${this.lc}[${this.complete.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5faaf13c6b0543d399815c03b9cdf80c)`); }\n\n // build the arg\n const arg = await this.argy({\n argData: {\n cmd: SubjectCmd.complete,\n },\n });\n\n // do it\n await this.witness(arg); // ignores return value\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion public api methods\n\n // #region witness sub-methods\n\n protected async witness_cmd({\n arg,\n }: {\n arg: SubjectCmdIbGib,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_cmd.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 2bf7cbcadba446fa92cb649906b2b260)`); }\n let { cmd } = arg.data!;\n switch (cmd) {\n case SubjectCmd.next:\n return this.witness_next({ ibGib: arg });\n case SubjectCmd.error:\n return this.witness_error({ ibGib: arg });\n case SubjectCmd.complete:\n return this.witness_complete({ ibGib: arg });\n default:\n // note: this is a call to the *super*.witness_cmd\n return super.witness_cmd({ arg });\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n private async witness_next({\n ibGib,\n }: {\n ibGib: SubjectCmdIbGib,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_next.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 600da780f13f5137a2f76aad344b2923)`); }\n\n if (this.isCompleteOrErrored) {\n if (logalot) { console.log(`${lc} this.isCompleteOrErrored is true. returning early without producing. (I: aa823831853b134b19657c8673838c23)`); }\n return ROOT;\n }\n\n // validate\n if ((ibGib.ibGibs ?? []).length !== 1) { throw new Error(`ibGib.ibGibs required. should contain one payload ibgib (E: 4046802ff96d4adfafcee7a74d96af5e)`); }\n\n // extract the payload\n const payloadIbGib = ibGib.ibGibs![0] as TIbGibIn_ie_Payload;\n\n // go ahead and persist this in our history\n if (this.data!.replay) { this._pastPayloads.push(payloadIbGib); }\n\n // dispatch to subscribers (serially)\n const subscriberTuples = Object.values(this._subscribers);\n for (let i = 0; i < subscriberTuples.length; i++) {\n const [subscription, observer] = subscriberTuples[i];\n\n // we remove subscribers on unsubscribe, but just in case we\n // will double-check here if we are still subscribed\n if (logalot) { console.log(`${lc} ensuring subscription not unsubscribed (I: ade3fd6d6ff2b5ec69eb8143e32ce223)`); }\n const unsubscribed = await subscription.unsubscribed();\n if (!unsubscribed) {\n if (logalot) { console.log(`${lc} subscription still active (I: b9ab83b28acecf0d823fdba46a81dc23)`); }\n // dispatch to observer's via its `next` fn\n await (observer as ObserverWitness<TIbGibIn_ie_Payload>).next(payloadIbGib);\n } else {\n debugger; // unexpected error state\n console.warn(`${lc} (UNEXPECTED) subscriber reference still held but is unsubscribed? skipping for now (i.e. won't remove subscriber) in case that code is in yielded execution and just hasn't gotten around to it with event loop (but that would be weird). (W: c116e799f6b9483c97fd030eb0dd09ea)`)\n }\n }\n return ROOT;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n private async witness_error({\n ibGib,\n }: {\n ibGib: SubjectCmdIbGib,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_error.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3367a73bc83c47f98d9ecfe426dc300e)`); }\n\n // validate\n if ((ibGib.ibGibs ?? []).length !== 1) { throw new Error(`ibGib.ibGibs required. should contain one error ibgib (E: 905474b45bcb4f0abe7bd4618f08f32c)`); }\n\n // extract the payload\n const errIbGib = ibGib.ibGibs![0] as ErrorIbGib_V1;\n\n // store the error in this observable\n this._pastError = errIbGib;\n\n // dispatch to subscribers (serially)\n const subscriberTuples = Object.values(this._subscribers);\n for (let i = 0; i < subscriberTuples.length; i++) {\n const [subscription, observerOrWitness] = subscriberTuples[i];\n\n // depends on if observer or witness...\n if (isObserver({ ibGib: observerOrWitness })) {\n // observer uses observer interface\n const observer = observerOrWitness as ObserverWitness<TIbGibIn_ie_Payload>;\n if (observer.error) {\n // we remove subscribers on unsubscribe, but just in case we\n // will double-check here if we are still subscribed\n const unsubscribed = await subscription.unsubscribed();\n if (!unsubscribed) {\n // dispatch to observer's via its `next` fn\n await observer.error(errIbGib);\n } else {\n console.warn(`${lc} (UNEXPECTED) subscriber reference still held but is unsubscribed? skipping for now (i.e. won't remove subscriber) in case that code is in yielded execution and just hasn't gotten around to it with event loop (but that would be weird). (W: 8946e97f00fd4146a470064b490a4c29)`)\n }\n } else {\n // no error handler for this observer\n if (logalot) { console.log(`${lc} no error handler for observer. skipping. (I: 59f4a1ee59a3a27d523d60cd761be923)`); }\n }\n } else {\n // observer is an ibGib witness (not an observer interface)\n await observerOrWitness.witness(errIbGib);\n }\n }\n return ROOT;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n private async witness_complete({\n ibGib,\n }: {\n ibGib: SubjectCmdIbGib,\n }): Promise<IbGib_V1> {\n const lc = `${this.lc}[${this.witness_complete.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4db180f465e24df9a4ded37fbd235558)`); }\n\n // set the flag on this observable\n this._isComplete = true;\n\n // dispatch to subscribers (serially)\n const subscriberTuples = Object.values(this._subscribers);\n for (let i = 0; i < subscriberTuples.length; i++) {\n const [subscription, observerOrWitness] = subscriberTuples[i];\n\n // depends on if observer or witness...\n if (isObserver({ ibGib: observerOrWitness })) {\n // observer uses observer interface\n const observer = observerOrWitness as ObserverWitness<TIbGibIn_ie_Payload>;\n if (observer.complete) {\n // we remove subscribers on unsubscribe, but just in case we\n // will double-check here if we are still subscribed\n const unsubscribed = await subscription.unsubscribed();\n if (!unsubscribed) {\n // dispatch to observer's via its `next` fn\n await observer.complete();\n } else {\n console.warn(`${lc} (UNEXPECTED) subscriber reference still held but is unsubscribed? skipping for now (i.e. won't remove subscriber) in case that code is in yielded execution and just hasn't gotten around to it with event loop (but that would be weird). (W: 1d98f35d2fdd4345954c947265d9fb85)`)\n }\n } else {\n // no error handler for this observer\n if (logalot) { console.log(`${lc} no error handler for observer. skipping. (I: 6a8a52c2012c464790eb406d2ae0383f)`); }\n }\n } else {\n // observer is an ibGib witness (not an observer interface)\n await observerOrWitness.witness(ibGib);\n }\n }\n return ROOT;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * validates against common witness qualities.\n *\n * Override this with a call to `super.validateThis` for custom validation\n * for descending witness classes.\n *\n * @returns validation errors common to all observable witnesses, if any errors exist.\n */\n protected async validateThis(): Promise<string[]> {\n const lc = `${this.lc}[${this.validateThis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!this.data) {\n\n }\n const errors: string[] = [\n // ...await super.validateThis(),\n // ...validateCommonSubjectData({ data: this.data }),\n ];\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion witness sub-methods\n\n // #region helpers\n\n /**\n * builds an arg ibGib.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async argy({\n argData,\n ibMetadata,\n noTimestamp,\n ibGibs,\n }: {\n argData: SubjectCmdData,\n ibMetadata?: string,\n noTimestamp?: boolean,\n ibGibs?: IbGib_V1[],\n }): Promise<SubjectCmdIbGib> {\n if (argData.cmd === ObservableCmd.subscribe) {\n return super.argy({ argData, ibMetadata, noTimestamp, ibGibs });\n } else {\n const arg = await argy_<SubjectCmdData, SubjectCmdRel8ns, SubjectCmdIbGib>({\n argData,\n ibMetadata,\n noTimestamp\n });\n if (ibGibs) { arg.ibGibs = ibGibs; }\n return arg;\n }\n }\n\n /**\n * builds a result ibGib, if indeed a result ibgib is required.\n *\n * This is only useful in witnesses that have more structured\n * inputs/outputs. For those that simply accept any ibgib incoming and\n * return a primitive like ib^gib or whatever, then this is unnecessary.\n *\n * wrapper convenience to avoid long generic calls.\n */\n async resulty({\n resultData,\n ibGibs,\n }: {\n resultData: SubjectResultData,\n ibGibs?: IbGib_V1[],\n }): Promise<SubjectResultIbGib> {\n const result = await resulty_<SubjectResultData, SubjectResultIbGib>({\n // ibMetadata: getSubjectResultMetadata({space: this}),\n resultData,\n });\n if (ibGibs) { result.ibGibs = ibGibs; }\n return result;\n }\n\n // #endregion helpers\n}\n\n/*\n * factory for random Subject witness.\n *\n * @see {@link DynamicFormFactoryBase}\n */\nexport class Subject_V1_Factory\n extends DynamicFormFactoryBase<SubjectData_V1, SubjectRel8ns_V1, Subject_V1> {\n\n protected lc: string = `[${Subject_V1_Factory.name}]`;\n\n getName(): string { return Subject_V1.name; }\n\n async newUp({\n data,\n rel8ns,\n }: {\n data?: SubjectData_V1,\n rel8ns?: SubjectRel8ns_V1,\n }): Promise<TransformResult<Subject_V1>> {\n const lc = `${this.lc}[${this.newUp.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n data ??= clone(DEFAULT_SUBJECT_DATA_V1);\n data = data!;\n rel8ns = rel8ns ?? DEFAULT_SUBJECT_REL8NS_V1 ? clone(DEFAULT_SUBJECT_REL8NS_V1) : undefined;\n data.uuid ||= await getUUID();\n let { classname } = data;\n\n const ib = getSubjectIb({ data });\n\n // subscription is a constant, so we dont need to create a\n // dependency graph or timeline or anything like that. it's just a\n // stone.\n const subscriptionIbGibDto =\n await constantIbGib<SubjectData_V1, SubjectRel8ns_V1>({\n parentPrimitiveIb: `witness ${classname}`,\n ib, data, rel8ns,\n }) as SubjectIbGib_V1;\n\n // replace the newIbGib which is just ib,gib,data,rel8ns with loaded\n // witness class (that has the witness function on it)\n const witnessIbGib = new Subject_V1(undefined, undefined);\n await witnessIbGib.loadIbGibDto(subscriptionIbGibDto);\n if (logalot) { console.log(`${lc} witnessDto: ${pretty(subscriptionIbGibDto)} (I: 6736d2b2ddf44fef9a1eb27078dfbf23)`); }\n\n return { newIbGib: witnessIbGib };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg({ error })}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async witnessToForm({ witness }: { witness: Subject_V1; }): Promise<DynamicForm> {\n const lc = `${this.lc}[${this.witnessToForm.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n let { data } = witness;\n if (!data) { throw new Error(`(UNEXPECTED) witness.data falsy? (E: 7b70c96e982d4f81b6ffda54da16b3b8)`); }\n if (logalot) { console.log(`${lc} data: ${pretty(data)} (I: 75abef56f5004a94b2113e3b1461ac25)`); }\n // be careful of order here because of TS type inference\n const idPool = await getIdPool({ n: 100 });\n const form = new SubjectFormBuilder()\n .with({ idPool })\n .name({ of: data.name!, required: false, })\n .description({ of: data.description ?? DEFAULT_DESCRIPTION_SUBJECT })\n .and<SubjectFormBuilder>()\n .and<DynamicFormBuilder>()\n .uuid({ of: data.uuid!, required: true })\n .classname({ of: data.classname! })\n .and<WitnessFormBuilder>()\n .commonWitnessFields({ data })\n .outputForm({\n formName: 'form',\n label: 'observable',\n });\n return Promise.resolve(form);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg({ error })}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async formToWitness({ form }: { form: DynamicForm; }): Promise<TransformResult<Subject_V1>> {\n let data: SubjectData_V1 = clone(DEFAULT_SUBJECT_DATA_V1);\n this.patchDataFromItems({ data, items: form.items, pathDelimiter: DEFAULT_DATA_PATH_DELIMITER });\n let resWitnessIbGib = await this.newUp({ data });\n return resWitnessIbGib;\n }\n\n}\n", "/*\n * @module subject helper/util/etc. functions\n *\n * this is where you will find helper functions like those that generate\n * and parse ibs for subject.\n */\n\n// import * as pathUtils from 'path';\n// import { statSync } from 'node:fs';\n// import { readFile, } from 'node:fs/promises';\n// import * as readline from 'node:readline/promises';\n// import { stdin, stdout } from 'node:process'; // decide if use this or not\n\nimport {\n extractErrorMsg, delay, getSaferSubstring,\n getTimestampInTicks, getUUID, pretty, clone,\n} from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { UUID_REGEXP, CLASSNAME_REGEXP, } from '@ibgib/helper-gib/dist/constants.mjs';\nimport { Gib, Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { IbGib_V1, } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { GIB, } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { validateGib, validateIb, validateIbGibIntrinsically, } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\n// import { IbGibSpaceAny } from '../../../witness/space/space-base-v1.mjs';\n// import { MetaspaceService } from '../../../witness/space/metaspace/metaspace-types.mjs';\nimport { WitnessFormBuilder } from '../../../witness/witness-form-builder.mjs';\n// import { IbGibSubjectAny } from './subject-v1.mjs';\nimport {\n SubjectData_V1, SubjectRel8ns_V1, SubjectIbGib_V1, SubjectWitness, DEFAULT_SUBJECT_DATA_V1,\n} from './subject-types.mjs';\nimport { SUBJECT_ATOM, SUBJECT_NAME_REGEXP, } from './subject-constants.mjs';\nimport { Observer } from '../observer/observer-types.mjs';\nimport { Subject_V1_Factory } from './subject-v1.mjs';\n\n/**\n * for logging. import this constant from your project.\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport function validateCommonSubjectData({\n data,\n}: {\n data?: SubjectData_V1,\n}): string[] {\n const lc = `[${validateCommonSubjectData.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (!data) { throw new Error(`Subject Data required (E: 207a82725648e2ef234c8bd3fa1a5312)`); }\n const errors: string[] = [];\n const {\n name, uuid, classname,\n } =\n data;\n\n if (name) {\n if (!name.match(SUBJECT_NAME_REGEXP)) {\n errors.push(`name must match regexp: ${SUBJECT_NAME_REGEXP} (E: de987eb8fea0b6232f60abf31815095c)`);\n }\n } else {\n errors.push(`name required.`);\n }\n\n if (uuid) {\n if (!uuid.match(UUID_REGEXP)) {\n errors.push(`uuid must match regexp: ${UUID_REGEXP} (E: 1a6dfda91ad51696f7456bc84dfea60e)`);\n }\n } else {\n errors.push(`uuid required.`);\n }\n\n if (classname) {\n if (!classname.match(CLASSNAME_REGEXP)) {\n errors.push(`classname must match regexp: ${CLASSNAME_REGEXP}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateCommonSubjectIbGib({\n ibGib,\n}: {\n ibGib: SubjectIbGib_V1,\n}): Promise<string[] | undefined> {\n const lc = `[${validateCommonSubjectIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: cec6bd96c70e61680fd0e6137d846a94)`); }\n const intrinsicErrors: string[] = await validateIbGibIntrinsically({ ibGib }) ?? [];\n\n if (!ibGib.data) { throw new Error(`ibGib.data required (E: 50b1815be5abb247f6774048bbaee538)`); }\n const ibErrors: string[] = [];\n let { SubjectClassname, SubjectName, SubjectId } =\n parseSubjectIb({ ib: ibGib.ib });\n if (!SubjectClassname) { ibErrors.push(`SubjectClassname required (E: bafa26247959d4fd9e41dbed8b839cf5)`); }\n if (!SubjectName) { ibErrors.push(`SubjectName required (E: d95f7740415c727797c1e26f4888cbe0)`); }\n if (!SubjectId) { ibErrors.push(`SubjectId required (E: f415b151b37fe80b99b403a1590f2e14)`); }\n\n const dataErrors = validateCommonSubjectData({ data: ibGib.data });\n\n let result = [...(intrinsicErrors ?? []), ...(ibErrors ?? []), ...(dataErrors ?? [])];\n if (result.length > 0) {\n return result;\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * builds/rebuilds the ib for Subject based on incoming `data` and `classname`.\n *\n * note that if `data.classname` is truthy, it must match `classname` if also\n * truthy. (`data` is required, but may not necessarily have `classname` in it.)\n *\n * @returns ib based on params\n */\nexport function getSubjectIb({\n data,\n classname,\n}: {\n data: SubjectData_V1,\n classname?: string,\n}): Ib {\n const lc = `[${getSubjectIb.name}]`;\n try {\n const validationErrors = validateCommonSubjectData({ data });\n if (validationErrors.length > 0) { throw new Error(`invalid Subject data: ${validationErrors} (E: 55620ac1f17e30a30a92850219f894ac)`); }\n if (classname) {\n if (data.classname && data.classname !== classname) { throw new Error(`classname does not match data.classname (E: 20e86cca70130839a49ad011c9a7aafa)`); }\n } else {\n classname = data.classname;\n if (!classname) { throw new Error(`classname required (E: 74e29ae0f618fee7e7ef72a30c654a6c)`); }\n }\n\n // ad hoc validation here. should centralize witness classname validation\n\n const { name, uuid } = data;\n return `witness ${SUBJECT_ATOM} ${classname} ${name} ${uuid}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Current schema is 'witness [SUBJECT_ATOM] [classname] [SubjectName] [SubjectId]'\n *\n * NOTE this is space-delimited\n */\nexport function parseSubjectIb({\n ib,\n}: {\n ib: Ib,\n}): {\n SubjectClassname: string,\n SubjectName: string,\n SubjectId: string,\n} {\n const lc = `[${parseSubjectIb.name}]`;\n try {\n if (!ib) { throw new Error(`Subject ib required (E: b29b305c5bc5ba7adf735a037ee4c012)`); }\n\n const pieces = ib.split(' ');\n\n return {\n SubjectClassname: pieces[2],\n SubjectName: pieces[3],\n SubjectId: pieces[4],\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport class SubjectFormBuilder extends WitnessFormBuilder {\n protected lc: string = `[${SubjectFormBuilder.name}]`;\n\n constructor() {\n super();\n this.what = 'subject';\n }\n\n // exampleSetting({\n // of,\n // required,\n // }: {\n // of: string,\n // required?: boolean,\n // }): SubjectFormBuilder {\n // this.addItem({\n // // Subject.data.exampleSetting\n // name: \"exampleSetting\",\n // description: `example description`,\n // label: \"Example Label\",\n // regexp: EXAMPLE_REGEXP,\n // regexpErrorMsg: EXAMPLE_REGEXP_DESC,\n // dataType: 'textarea',\n // value: of,\n // required,\n // });\n // return this;\n // }\n\n}\n\n/**\n * helper function to determine if the given `ibGib` is an observer, i.e.,\n * fulfills the {@link Observer} contract.\n *\n * atow (11/2023) the minimal requirement is `ibGib.next` to be a function.\n *\n * @returns true if fulfills the {@link Observer} contract.\n */\nexport function isObserver({\n ibGib,\n}: {\n ibGib: IbGib_V1,\n}): boolean {\n const lc = `[${isObserver.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b54c252104f710c12951aa43b6ead323)`); }\n return typeof (ibGib as unknown as Observer).next === 'function';\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n// #region sugar\n\n/**\n * Uses {@link Subject_V1_Factory} to new up a blank subject.\n *\n * ## future\n *\n * in the future, will see about adding a space for persisting this subject (and\n * possibly published events).\n *\n * @returns subject\n */\nexport async function newupSubject<\n TPayloadIbGib extends IbGib_V1 = IbGib_V1\n>({\n data,\n replay,\n}: {\n data?: SubjectData_V1,\n replay?: boolean,\n} = {}): Promise<SubjectWitness<TPayloadIbGib>> {\n const subjectFactory = new Subject_V1_Factory();\n\n // starting data\n data ??= clone(DEFAULT_SUBJECT_DATA_V1) as SubjectData_V1;\n\n // additional options\n if (replay) { data.replay = true; }\n\n // create it\n const resTransform = await subjectFactory.newUp({ data });\n\n // return it\n return resTransform.newIbGib as SubjectWitness<TPayloadIbGib>;\n}\n\n// #endregion sugar\n", "import { AnonymousFnWitnessData_V1 } from \"./anonymous-fn-types.mjs\";\n\nexport const ANONYMOUS_FN_ATOM = 'anon_fn';\n\nexport const DEFAULT_ANONYMOUS_FN_DATA_V1: AnonymousFnWitnessData_V1 = {\n fnHash: '',\n};\n", "import { GLOBAL_LOG_A_LOT } from \"../../core-constants.mjs\";\nimport { WitnessFn } from \"../witness-types.mjs\";\nimport { ANONYMOUS_FN_ATOM } from \"./anonymous-fn-constants.mjs\";\nimport { AnonymousFnWitnessData_V1 } from \"./anonymous-fn-types.mjs\";\nimport { AnonymousFnWitness_V1 } from \"./anonymous-fn-v1.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport function getAnonymousFnIb({\n data,\n}: {\n data: AnonymousFnWitnessData_V1,\n}): string {\n const lc = `[${getAnonymousFnIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 37bb06e0390c5bcadf04501727d64923)`); }\n if (!data?.fnHash) { throw new Error(`data.fnHash required (E: 2e560f2c59822bc5ba024d4a8e99d323)`); }\n return `witness ${ANONYMOUS_FN_ATOM} ${data.fnHash}`;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * wraps a fn in an anonymous witness.\n *\n * @param fn fn to execute\n * @returns anonymous witness ibgib\n */\nexport async function fnToWitness(fn: WitnessFn): Promise<AnonymousFnWitness_V1> {\n const lc = `[${fnToWitness.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e64fe14287de9716f2e5ff3bf9d93923)`); }\n let witness = new AnonymousFnWitness_V1(fn);\n return witness;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { clone, hash } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { getGib } from \"@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs\";\n\nimport { Witness, WitnessFn, } from \"../witness-types.mjs\";\nimport { ANONYMOUS_FN_ATOM, DEFAULT_ANONYMOUS_FN_DATA_V1 } from \"./anonymous-fn-constants.mjs\";\nimport { getAnonymousFnIb } from \"./anonymous-fn-helper.mjs\";\nimport { AnonymousFnWitnessData_V1, AnonymousFnWitnessIbGib_V1, AnonymousFnWitnessRel8ns_V1, } from \"./anonymous-fn-types.mjs\";\n\n/**\n * Helper class that wraps a witness function.\n *\n * @see {@link AnonymousFnWitnessData_V1}\n * @see {@link AnonymousFnWitnessRel8ns_V1}\n * @see {@link WitnessFn}\n */\nexport class AnonymousFnWitness_V1\n implements\n Witness<IbGib_V1, IbGib_V1, AnonymousFnWitnessData_V1, AnonymousFnWitnessRel8ns_V1>,\n AnonymousFnWitnessIbGib_V1 {\n\n ib: string = ANONYMOUS_FN_ATOM.concat();\n gib?: string | undefined = GIB;\n data?: AnonymousFnWitnessData_V1 | undefined = clone(DEFAULT_ANONYMOUS_FN_DATA_V1);\n rel8ns?: AnonymousFnWitnessRel8ns_V1 | undefined;\n\n constructor(public fn: WitnessFn) {\n if (!fn) { throw new Error(`fn required (E: b1e1478f466a2a347b75e7c336f8d323)`); }\n }\n\n async witness(arg: IbGib_V1): Promise<IbGib_V1 | undefined> {\n this.data!.fnHash = await hash({ s: this.fn.toString() });\n this.ib = getAnonymousFnIb({ data: this.data! });\n this.gib = await getGib({ ibGib: this });\n return this.fn(arg);\n }\n\n}\n", "import { extractErrorMsg } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGib_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { ROOT } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../../../core-constants.mjs\";\nimport { ErrorIbGib_V1 } from \"../../error/error-types.mjs\";\nimport { isIbGib } from \"../../other/ibgib-helper.mjs\";\nimport { getErrorIbGib, isError } from \"../../error/error-helper.mjs\";\nimport { Observer, ObserverWitness } from \"./observer-types.mjs\";\nimport { WitnessFn } from \"../../../witness/witness-types.mjs\";\nimport { AnonymousFnWitness_V1 } from \"../../../witness/anonymous-fn/anonymous-fn-v1.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Determines type of incoming `err` and pulls out the error msg accordingly.\n *\n * ## note on not using {@link extractErrorMsg}\n *\n * {@link extractErrorMsg} is in helper-gib, which despite the name, does not\n * contain ibgib-specific types. So we can't pass in an ibGib and have it\n * extract the error msg.\n *\n * @returns error msg from incoming err\n */\nexport function extractObsErrMsg({\n err,\n}: {\n err: ErrorIbGib_V1 | Error | string,\n}): string {\n const lc = `[${extractObsErrMsg.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 96f8b767c50f24768ced7beebb291723)`); }\n if (isIbGib(err)) {\n let ibGib = err as IbGib_V1;\n if (!(err as IbGib_V1).data) { throw new Error(`err isIbGib but err.data is false. (E: 151a6bab647c638c454fd277ac468f23)`); }\n if (isError({ ibGib: err as IbGib_V1 })) {\n return (err as ErrorIbGib_V1).data!.raw;\n } else {\n // shouldn't get here because function signature but hey ynk\n throw new Error(`(UNEXPECTED) err isIbGib but not ErrorIbGib_V1? (E: 81c2283fad5db3485c6e9acedbda9723)`);\n }\n } else {\n return extractErrorMsg(err);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * this is meant to be a wrapper of non-ibgib-like lambdas.\n *\n * So you take normal, mostly non-ibgib anonymous lambdas (that do indeed\n * have ibgib's as their inputs/outputs) and you wrap it here to get an\n * {@link ObserverWitness} which is an actual witness ibGib.\n * @param observer with regularish lambdas in a javascript object (not an ibgib)\n * @returns observer ibgib witness with formal ibgib witness signatures and the other ibgib properties: `ib`, `gib`, `data`, `rel8ns`\n */\nexport function fnObs<T extends IbGib_V1 = IbGib_V1>(\n observerOrFn: Observer<T> | ((ibGib: T) => Promise<void>)\n): ObserverWitness<T> {\n const lc = `[${fnObs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3d2c3658a0fda83ece1f2b095a365823)`); }\n\n let observer: Observer<T>;\n if (typeof observerOrFn === 'function') {\n observer = { next: observerOrFn, };\n } else {\n observer = observerOrFn;\n }\n\n if (!observer.next) { throw new Error(`observer.next required (typeof observerOrFn !== 'function') (E: da944e93b32ab5918f11751bcd651823)`); }\n\n const fnNext: WitnessFn<T> = async (ibGib) => {\n await observer.next(ibGib);\n return ROOT;\n };\n /**\n * no idea what im doing here really...making an anonymous ibgib\n * essentially, but not sure how the witness fn would actually be used.\n * @param ibGib coming down the pipe?\n * @returns `ROOT`\n */\n const fnWitness: WitnessFn<T | ErrorIbGib_V1> = async (ibGib) => {\n if (ibGib.ib === 'complete') {\n if (observer.complete) { await observer.complete(); }\n } else if (isError({ ibGib })) {\n if (observer.error) {\n await observer.error(ibGib as ErrorIbGib_V1)\n }\n } else {\n await observer.next(ibGib as T);\n }\n return ROOT;\n };\n\n // I'm wrapping these in anonymous fn witnesses, but do I need to?\n let nextAnonFnWitness = new AnonymousFnWitness_V1(fnNext as WitnessFn); // cast should not be necessary\n let witnessAnonFnWitness = new AnonymousFnWitness_V1(fnWitness as WitnessFn); // cast should not be necessary\n\n // const observerWitness: SubjectWitness<T> = {\n const observerWitness: ObserverWitness<T> = {\n ib: 'observer',\n witness: async (x: T) => await witnessAnonFnWitness.witness(x),\n next: async (x: T) => { await nextAnonFnWitness.witness(x); },\n // isComplete: false,\n // isErrored: false,\n // isCompleteOrErrored: false,\n // asObservable: () => { throw new Error(`asObservable not impl on anonymous fn witness (E: d127d1822dbd90e7134cef75e4e23c23)`); },\n // subscribe: () => { throw new Error(`subscribe not impl on anonymous fn witness (E: 11ce7903626e8d1c3d27dc28f1e5cd23)`); },\n };\n\n let fnError = observer.error ?? (async (error: string | ErrorIbGib_V1 | Error) => {\n let errorMsg: string;\n if (typeof error === 'string') {\n errorMsg = extractErrorMsg(error);\n } else if (!!(error as any).ib) {\n // error ibgib\n if (isError({ ibGib: error as IbGib_V1 })) {\n errorMsg = extractErrorMsg((error as ErrorIbGib_V1).data!.raw);\n } else {\n throw new Error(`${lc} (UNEXPECTED) first off, observer.error is falsy. secondly, error came down pipeline and has an \"ib\" property but is not an ErrorIbGib_V1? (E: 0a2a46b9620b4a6a84c7ba1100da537b)`);\n }\n } else if (error instanceof Error) {\n errorMsg = extractErrorMsg(error as any)\n } else if (typeof (error as any).message === 'string') {\n errorMsg = extractErrorMsg((error as any).message)\n } else {\n errorMsg = '[unknown thing came down pipe that ain\\'t an error]';\n }\n console.error(`Error occurred but observer.error is falsy. error: ${errorMsg} (E: 822c60c7c4d542efacd5c2dea7e88062)`)\n });\n const errorAnonFnWitness =\n new AnonymousFnWitness_V1(async x => { fnError(x as ErrorIbGib_V1); return ROOT; });\n observerWitness.error = async (x: string | ErrorIbGib_V1 | Error) => {\n // if (observerWitness.isCompleteOrErrored) {\n // console.warn(`${lc} observerWitness.error triggered but observerWitness already complete or errored. (W: 85f8426d70404208b721a9de2876bbc2)`)\n // return; /* <<<< returns early */\n // } else {\n // // do these before any more handling in case there is some problem.\n // (observerWitness as any).isErrored = true;\n // (observerWitness as any).isCompleteOrErrored = true;\n // }\n // coerce non-ibgib errors into ErrorIbGib_V1\n if (typeof x === 'string') {\n x = await getErrorIbGib({ rawMsg: x });\n } else if (x instanceof Error) {\n x = await getErrorIbGib({ rawMsg: x.message });\n }\n try {\n await errorAnonFnWitness.witness(x);\n } catch (anotherError) {\n if (observer.error) {\n console.error(`${lc} there was another error when executing errorAnonFnWitness.witness (wrapper of caller's observer.error) trapping this. (E: 8fa3c4e633df4491a82951e3b677d9a9)`)\n } else {\n console.error(`${lc} there was another error when executing errorAnonFnWitness.witness (caller's observer.error was falsy). trapping this. (E: f5ff2db0d762487287139a4175eb7689)`)\n }\n }\n };\n\n if (observer.complete) {\n let fnComplete = observer.complete;\n let completeAnonFnWitness = new AnonymousFnWitness_V1(async (_) => {\n await fnComplete();\n return ROOT;\n });\n\n observerWitness.complete = async () => {\n // (observerWitness as any).isComplete = true;\n // (observerWitness as any).isCompleteOrErrored = true;\n try {\n await completeAnonFnWitness.witness(ROOT);\n } catch (error) {\n console.error(`${lc} there was an error when executing completeAnonFnWitness (wrapper for observer.complete fn) error: ${extractErrorMsg(error)} (E: c9e61b08429e42c1b85d2215f735ba2f)`)\n }\n };\n }\n\n return observerWitness;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "/**\n * @module secret constants\n *\n * constants are in this file!\n */\n\n// /**\n// * example enum-like type+const that I use in ibgib. sometimes i put\n// * these in the types.mts and sometimes in the const.mts, depending\n// * on context.\n// */\n// export type SomeEnum =\n// 'ib' | 'gib';\n// export const SomeEnum = {\n// ib: 'ib' as SomeEnum,\n// gib: 'gib' as SomeEnum,\n// } satisfies { [key: string]: SomeEnum };\n// export const SOME_TYPE_VALUES: SomeEnum[] = Object.values(SomeEnum);\n\n/**\n * atom used in ibs\n */\nexport const SECRET_ATOM = 'secret';\n\n/**\n * default regexp for a simple name string.\n */\nexport const SECRET_NAME_REGEXP = /^[a-zA-Z0-9_\\-.]{1,255}$/;\n\n/**\n * A secrets ibgib uses this rel8n name for its children secrets.\n */\nexport const SECRET_REL8N_NAME = 'secret';\n\n/**\n * this is the length of the substring that we'll create when generating partial\n * hash substrings for password \"probably correct\" verification. this check is\n * made only for the user's convenience to see if they \"probably\" typed in their\n * password correctly. If they typo the password or just type in the wrong one,\n * there is an approximately 1/250 chance on average\n *\n * @see `SecretInfo_Password.passwordProbablyCorrectInfo` in secret-types.mts\n *\n * READ THE DOCS FOR THAT LINK\n */\nexport const DEFAULT_PASSWORD_CHECK_SUBSTRING_LENGTH = 4;\n", "/**\n * @module outer-space\n * Outer spaces are spaces connecting local inner spaces.\n * ATOW there is just sync spaces, but definitely just the beginning.\n *\n * ## on future implementations, CRDT-like behavior\n *\n * I just realized that when merging, I can actually create a meta transform\n * ibgib to maintain the order of transforms.\n */\n\nimport { Ib, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../core-constants.mjs';\nimport { SpaceType, SpaceSubtype, VALID_SPACE_SUBTYPES, VALID_SPACE_TYPES, } from '../space-types.mjs';\nimport { ParticipantInfo, StatusCode, StatusIbInfo, SyncSpaceIbGib, } from './outer-space-types.mjs';\nimport { OUTER_SPACE_DEFAULT_IB_DELIMITER } from './outer-space-constants.mjs';\nimport { IbGibSpaceAny } from '../space-base-v1.mjs';\nimport { getSpecialRel8dIbGibs } from '../space-helper.mjs';\nimport { SpecialIbGibType } from '../../../common/other/other-types.mjs';\nimport { SYNC_SPACE_REL8N_NAME } from '../space-constants.mjs';\nimport { SpaceFactoryFnMap } from '../metaspace/metaspace-types.mjs';\n\n\n/**\n * for verbose logging\n */\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Composes ib with given params info.\n *\n * @returns ib string with given info encoded\n */\nexport function getStatusIb({\n sagaId,\n statusCode,\n spaceType,\n spaceSubtype,\n delimiter,\n}: StatusIbInfo): string {\n const lc = `[${getStatusIb.name}]`;\n try {\n if (!sagaId) { throw new Error(`sagaId required. (E: cfc923bb29ee4aa788e947b6416740e6)`); }\n if (statusCode === null || statusCode === undefined) { throw new Error(`status code required. (E: 4e0d232a9955496695012623c2e17ca2)`); }\n if (!Object.values(StatusCode).includes(statusCode)) { throw new Error(`invalid status code (${statusCode}) (E: 91d7655424c44d9680fff099ee2b54d2)`); }\n if (!spaceType) { throw new Error(`spaceType required. (E: 86e98694a56a4f599e98e50abf0eed43)`); }\n if (!spaceSubtype) { throw new Error(`spaceSubtype required. (E: 4857d4677ee34e95aeb2251dd633909e)`); }\n\n delimiter = delimiter || OUTER_SPACE_DEFAULT_IB_DELIMITER;\n\n return `status ${sagaId} ${statusCode} ${spaceType} ${spaceSubtype}`;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Parses the given `statusIb` and returns the info object.\n *\n * @returns info from parsing the status ib\n */\nexport function getStatusIbInfo({\n statusIb,\n delimiter,\n}: {\n statusIb: Ib,\n delimiter?: string,\n}): StatusIbInfo {\n const lc = `[${getStatusIb.name}]`;\n try {\n if (!statusIb) { throw new Error(`statusIb required. (E: 09e23e8622cf456cadb0c3d0aadc3be9)`); }\n\n delimiter = delimiter || OUTER_SPACE_DEFAULT_IB_DELIMITER;\n\n // atow `status ${sagaId} ${statusCode} ${spaceType} ${spaceSubtype}`;\n const pieces = statusIb.split(delimiter);\n\n const sagaId = pieces[1];\n if (sagaId === null || sagaId === undefined) { throw new Error(`sagaId is null/undefined. (E: 5de2861a6afb48e1a1c89d0402a4ea63)`); }\n\n const statusCode = pieces[2] as StatusCode; // tenatively cast as StatusCode\n if (!Object.values(StatusCode).includes(statusCode)) { throw new Error(`invalid/unknown status code (${statusCode}) (E: 7580860df7b344b3992148552e80a85e)`); }\n\n const spaceType = pieces[3] as SpaceType;\n if (spaceType === null || spaceType === undefined) { throw new Error(`spaceType is null/undefined. (E: 12473d35e77b451bb59bb05c03cb8b64)`); }\n if (!VALID_SPACE_TYPES.includes(spaceType)) { throw new Error(`invalid/unknown spaceType (${spaceType}) (E: d3ba9add427f49dda34f265f3225d9db)`); }\n\n const spaceSubtype = pieces[4] as SpaceSubtype;\n if (spaceSubtype === null || spaceSubtype === undefined) { throw new Error(`spaceSubtype is null/undefined. (E: 6da7ae919d0b4a22b4ee685520b6c946)`); }\n if (!VALID_SPACE_SUBTYPES.includes(spaceSubtype)) { throw new Error(`invalid/unknown spaceSubtype (${spaceSubtype}) (E: 703ed1aee44447a294b3e1cf0984baba)`); }\n\n return { statusCode, spaceType, spaceSubtype, sagaId, delimiter };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport async function getSyncSpaces({\n space,\n}: {\n space: IbGibSpaceAny,\n}): Promise<SyncSpaceIbGib[]> {\n const lc = `[${getSyncSpaces.name}]`;\n try {\n if (!space) { throw new Error(`space required. (E: c03f80eca6b045b9a73b0aafa44cdf26)`); }\n let syncSpaces = await getSpecialRel8dIbGibs<SyncSpaceIbGib>({\n type: SpecialIbGibType.outerspaces,\n rel8nName: SYNC_SPACE_REL8N_NAME,\n space,\n });\n return syncSpaces;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * gets the sync space ibgibs referenced in the given local {@link localSpace}\n * and loads them into their corresponding witness classes.\n *\n * note: atow (03/2024) this throws if a factory function isn't found for ANY of\n * the sync spaces found. later on, when multiple kinds of sync spaces are in\n * existence, this behavior should change because it would be quite possible\n * that we have multiple spaces that may not have a loaded factory function\n * available.\n *\n * @see {@link SpaceFactoryFnMap}\n *\n * @returns sync space witnesses\n */\nexport async function getSyncSpaces_witnesses({\n localSpace,\n spaceFactoryFns,\n}: {\n /**\n * user's local space that contains references to outer space \"proxy\"\n * ibgibs.\n */\n localSpace: IbGibSpaceAny,\n /**\n * factory function map (by type/subtype) that generates the space witnesses\n * from the space dtos.\n *\n * @see {@link SpaceFactoryFnMap}\n */\n spaceFactoryFns: SpaceFactoryFnMap,\n}): Promise<IbGibSpaceAny[]> {\n const lc = `[${getSyncSpaces_witnesses.name}]`;\n try {\n if (!localSpace) { throw new Error(`localSpace required. (E: c03f80eca6b045b9a73b0aafa44cdf26)`); }\n let resSpaceWitnesses: IbGibSpaceAny[] = [];\n\n const syncSpaceDtos = await getSyncSpaces({ space: localSpace });\n for (let i = 0; i < syncSpaceDtos.length; i++) {\n const syncSpaceDto = syncSpaceDtos[i];\n if (!syncSpaceDto.data) { throw new Error(`(UNEXPECTED) syncSpaceDto.data falsy? (E: 5404f124b8bb781c0a52b3cc9f8e6524)`); }\n const { type, subtype } = syncSpaceDto.data;\n if (!type) { throw new Error(`(UNEXPECTED) syncSpaceDto.data.type falsy? (E: b3461e0df562d301fc84d68d95f91424)`); }\n if (!subtype) { throw new Error(`(UNEXPECTED) syncSpaceDto.data.subtype falsy? (E: 524c471119564b4b817261f9e1edcafb)`); }\n const fnFactory_typeSubset = spaceFactoryFns[syncSpaceDto.data.type] ?? {};\n const fnFactory = fnFactory_typeSubset[syncSpaceDto.data.subtype];\n if (!fnFactory) { throw new Error(`(UNEXPECTED) no factory function found for type (${type}) and subtype (${subtype})? (E: fd726f9049ade511f679d1de621dec24)`); }\n const spaceWitness = await fnFactory(syncSpaceDto);\n resSpaceWitnesses.push(spaceWitness);\n }\n\n if (syncSpaceDtos.length !== resSpaceWitnesses.length) {\n throw new Error(`(UNEXPECTED) syncSpaceDtos.length !== resSpaceWitnesses.length? (E: c85b1c93fce972a57683da727e6dc224)`);\n }\n\n return resSpaceWitnesses;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport function getSrcLocalSpaceId({\n participants,\n}: {\n participants: ParticipantInfo[],\n}): string {\n const lc = `[${getSrcLocalSpaceId.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 43c9a4f1fa1bbc944b98f8eed2f81924)`); }\n\n const participants_src = participants.filter(x => x.s_d === 'src');\n if (participants_src.length !== 1) { throw new Error(`(UNEXPECTED) participants_src.length !== 1? atow (03/2024) only one src participant is expected. (E: ed4b3ae15f5da34c77655553aaf82224)`); }\n\n return participants_src.at(0)!.id;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { delay, getUUID, groupBy, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { encrypt, decrypt, } from '@ibgib/encrypt-gib/dist/encrypt-decrypt.mjs';\nimport { DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE, DEFAULT_ALPHABET_INDEXING_MODE_LEGACY } from '@ibgib/encrypt-gib/dist/constants.mjs';\nimport { IbGib_V1, } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { GIB, GIB_DELIMITER, IB, ROOT, } from '@ibgib/ts-gib/dist/V1/constants.mjs';\nimport { IbGibAddr, TjpIbGibAddr, TransformResult, } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbGibAddr, } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { getGib, getGibInfo, isPrimitive } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT, GLOBAL_TIMER_NAME } from '../../../core-constants.mjs';\nimport {\n DeleteIbGibOpts, DeleteIbGibResult,\n GetIbGibOpts, GetIbGibResult,\n PutIbGibOpts, PutIbGibResult\n} from '../../../common/other/other-types.mjs';\nimport { TagIbGib_V1 } from '../../../common/tag/tag-types.mjs';\nimport {\n OuterSpaceData,\n ParticipantInfo, StatusCode, SyncSagaInfo, SyncSpaceIbGib, SyncSpaceOptionsData,\n SyncSpaceOptionsIbGib, SyncSpaceResultIbGib, SyncStatusIbGib,\n} from '../../../witness/space/outer-space/outer-space-types.mjs';\nimport { IbGibSpaceData, IbGibSpaceRel8ns, SpaceId } from '../../../witness/space/space-types.mjs';\nimport { IbGibSpaceAny } from '../../../witness/space/space-base-v1.mjs';\nimport { BootstrapIbGib } from '../../../witness/space/bootstrap/bootstrap-types.mjs';\nimport { IbGibTimelineUpdateInfo, SpecialIbGibType } from '../../../common/other/other-types.mjs';\nimport { RootData } from '../../../common/root/root-types.mjs';\nimport {\n CiphertextData, CiphertextIbGib_V1, CiphertextRel8ns,\n EncryptionData_V1, EncryptionIbGib_V1, EncryptionInfo_EncryptGib,\n EncryptionMethod,\n} from '../../../common/encrypt/encrypt-types.mjs';\nimport { RobbotIbGib_V1 } from '../../../witness/robbot/robbot-types.mjs';\nimport { AppIbGib_V1 } from '../../../witness/app/app-types.mjs';\nimport { constantIbGib, getTimelinesGroupedByTjp, hasTjp } from '../../../common/other/ibgib-helper.mjs';\nimport {\n getValidatedBootstrapIbGib, getLocalSpace, execInSpaceWithLocking,\n updateBootstrapIbGib, getSpaceArgMetadata, createTagIbGibAndSundry,\n getConfigAddr, setConfigAddr, setCurrentRoot, rel8ToCurrentRoot,\n rel8ToSpecialIbGib, registerNewIbGib, persistTransformResult, getFromSpace,\n putInSpace, deleteFromSpace, getLatestAddrs, getTjpIbGib, getSpecialIbGib,\n getSpecialRel8dIbGibs, /*createRobbotIbGib, */ trash, archive, parseSpaceIb,\n} from '../../../witness/space/space-helper.mjs';\nimport { getDependencyGraph, GetDependencyGraphOptions } from '../../../common/other/graph-helper.mjs';\nimport { RobbotPromptResult } from '../../../witness/robbot/robbot-types.mjs';\nimport { createNewRobbot, validateCommonRobbotData, validateCommonRobbotIbGib } from '../../../witness/robbot/robbot-helper.mjs';\nimport { AppPromptResult } from '../../../witness/app/app-types.mjs';\nimport { createNewApp, } from '../../../witness/app/app-helper.mjs';\nimport { IbGibCacheService } from '../../../common/cache/cache-types.mjs';\nimport { BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY, BOOTSTRAP_IBGIB_ADDR } from '../../../witness/space/bootstrap/bootstrap-constants.mjs';\nimport { DEFAULT_SECONDS_VALID_LOCAL, SYNC_SPACE_REL8N_NAME } from '../../../witness/space/space-constants.mjs';\nimport {\n CIPHERTEXT_ATOM, DEFAULT_ENCRYPTION_HASH_ALGORITHM,\n DEFAULT_ENCRYPTION_INITIAL_RECURSIONS,\n DEFAULT_ENCRYPTION_RECURSIONS_PER_HASH, DEFAULT_ENCRYPTION_SALT_STRATEGY,\n ENCRYPTION_REL8N_NAME,\n} from '../../../common/encrypt/encrypt-constants.mjs';\nimport { ROBBOT_REL8N_NAME } from '../../../witness/robbot/robbot-constants.mjs';\nimport { APP_REL8N_NAME } from '../../../witness/app/app-constants.mjs';\nimport { AUTOSYNC_ALWAYS_REL8N_NAME } from '../../../common/other/other-constants.mjs';\nimport {\n MetaspaceInitializeOptions, CreateLocalSpaceOptions,\n LocalSpaceFactoryFunction, MetaspaceFactory\n} from './metaspace-types.mjs';\nimport { MetaspaceService, TempCacheEntry } from './metaspace-types.mjs';\nimport { newupSubject } from '../../../common/pubsub/subject/subject-helper.mjs';\nimport { ObservableWitness, } from '../../../common/pubsub/observable/observable-types.mjs';\nimport { SubjectWitness } from '../../../common/pubsub/subject/subject-types.mjs';\nimport { SubscriptionWitness } from '../../../common/pubsub/subscription/subscription-types.mjs';\nimport { fnObs } from '../../../common/pubsub/observer/observer-helper.mjs';\nimport { SecretData_V1, SecretIbGib_V1, SecretInfo_Password } from '../../../common/secret/secret-types.mjs';\nimport { SECRET_REL8N_NAME } from '../../../common/secret/secret-constants.mjs';\nimport { getSrcLocalSpaceId } from '../outer-space/outer-space-helper.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * All-purpose mega service (todo: which we'll need to break up!) to interact\n * with ibgibs at the app/device level.\n *\n * This works with the local app user space.\n *\n * ## regarding special ibgibs\n *\n * Special ibgibs' behaviors are what hold in other apps configuration data.\n * Of course the difference is that most special ibgibs can leverage the \"on-chain\"\n * functionality of \"regular\" ibgibs.\n *\n * There are a couple meta ibgibs (which I also call \"special\"):\n * * roots^gib\n * * tracks other special root^gib ibgibs, which are like local app-level indexes.\n * * tags^gib\n * * tracks other special tag^gib ibgibs, which you can apply to any ibgib\n * * latest^gib\n * * tracks mappings between tjp -> latest ib^gib address\n * * ephemeral (deletes past rel8ns and past ibGib frames)\n * * ...\n *\n * ## regarding latest ibgibs\n *\n * The tjp (temporal junction point) defines atow the beginning of an ibGib\n * timeline. it's like the birthday for an ibGib. (Or you can think if it as\n * the id for the stream of ibgib frames in a given timeline.)\n *\n * The latest ibGib in that timeline is also special, because it's often what\n * you want to work with.\n *\n * So ideally, when an ibgib, A, has a tjp A1, and it is updated to A2, A3, An\n * via `mut8` and/or `rel8` transforms, that ibgib creates a single timeline.\n * This service attempts to track the relationship between that starting tjp\n * address and its corresponding latest frame in that timeline, i.e., A1 -> An.\n *\n * ### mapping persistence implementation details\n *\n * The latest ibGib service is backed by a special ibgib that maintains the\n * mapping index. It does this by rel8-ing that special backing ibgib via the\n * tjp pointer, e.g. [special latest ibgib^XXX000].rel8ns[A^TJP123] ===\n * [A^N12345] . It does this via the ib^gib content address pointer, so this\n * becomes a mapping from A^TJP123 to A^N12345.\n *\n * This backing ibGib is special (even for special ibGibs) in that:\n * * it does not relate itself with the current root of the application\n * * it does not maintain references to its past (i.e. rel8ns['past'] === [])\n * * it DELETES its previous incarnation from the files service\n *\n * In other words, this service is meant to be as ephemeral as possible. I am\n * keeping it as an ibGib and not some other data format (like straight in\n * storage/some other db) because I've found this is often useful and what I end\n * up doing anyway to leverage other ibgib behavior. For example, in the future\n * it may be good to take snapshots, which is a simple copy operation of the\n * file persistence.\n *\n * ### current naive implementation notes\n *\n * questions:\n * * What do we want to do if we can't locate an ibGib record?\n * * How/when do we want to alert the user/our own code that we've found\n * multiple timelines for an ibGib with a tjp (usually a thing we want to\n * avoid)?\n * * Who do we want to notify when new ibGibs arrive?\n * * How often do we want to check external sources for latest?\n * * When do we get to merging ibGib timelines?\n *\n * This is behavior that is somewhat taken care of, e.g. in git, with the HEAD\n * pointer for a repo. But we're talking about here basically as a metarepo or\n * \"repo of repos\", and unlike git, we don't want our HEAD metadata living \"off\n * chain\" (outside of the DLT itself that it's modifying). So eventually, what\n * we want is just like what we want with ALL ibGibs: perspective. From \"the\n * app\"'s perspective, the latest is mapped. But really, apps can't view slices\n * of ibGib graphs in all sorts of interesting ways and still be productive &\n * beneficial to the ecosystem as a whole.\n */\nexport abstract class MetaspaceBase implements MetaspaceService {\n\n // we won't get an object back, only a DTO ibGib essentially\n protected lc: string = `[${MetaspaceBase.name}]`;\n\n instanceId: string = (new Date()).toUTCString();\n\n protected _initialized: boolean = false;\n get initialized(): boolean { return this._initialized; }\n\n protected _initializedSubj: SubjectWitness<any> | undefined;\n initialized$: ObservableWitness<any> | undefined;\n\n protected _initializing: boolean = false;\n get initializing(): boolean { return this._initializing; }\n\n protected _latestSubj: SubjectWitness<IbGibTimelineUpdateInfo> | undefined;\n latestObs: ObservableWitness<IbGibTimelineUpdateInfo> | undefined;\n\n /**\n * gets the current local user space\n */\n async getLocalUserSpace({\n lock = false,\n localSpaceId,\n }: {\n /**\n * If true, then we lock by bootstrap/spaceId before trying to retrieve.\n *\n * @default true\n */\n lock?: boolean,\n /**\n * If provided, will look for the space via this id in the bootstrap ibgib.\n * If not provided, will use the bootstrap ibgib's default spaceId.\n */\n localSpaceId?: SpaceId,\n }): Promise<IbGibSpaceAny | undefined> {\n const lc = `${this.lc}[${this.getLocalUserSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // if we're not explicit with skipLock, go by platform\n // we only need to lock when doing the web, because we could\n // have multiple tabs open.\n lock ??= false;\n // if (lock === undefined) {\n // if (!this._platform) { this._platform = Capacitor.getPlatform(); }\n // if (logalot) { console.log(`${this.lc} platform: ${this._platform}`); }\n // lock = this._platform === 'web';\n // }\n\n const bootstrapIbGib =\n await getValidatedBootstrapIbGib({ zeroSpace: this.zeroSpace }) ?? undefined;\n\n const localSpace =\n await getLocalSpace<IbGibSpaceAny>({\n zeroSpace: this.zeroSpace,\n bootstrapIbGib,\n lock,\n callerInstanceId: this.instanceId,\n localSpaceId,\n fnDtoToSpace: (spaceDto: IbGib_V1) => this.metaspaceFactory.fnDtoToSpace!(spaceDto),\n localSpaceCacheSvc: this.cacheSvc,\n });\n\n return localSpace;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * gets all local user spaces known in bootstrap ibgib, according to\n * spaceIds property\n *\n * (`bootstrapIbGib.data[BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY]` atow)\n *\n * ## example bootstrap ibgib atow\n *\n ```json\n {\n \"ib\":\"bootstrap\",\n \"gib\":\"gib\",\n \"data\":{\n \"defaultSpaceId\":\"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\",\n \"spaceIds\":[\"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\"]\n },\n \"rel8ns\":{\n \"d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33\":[\n \"witness space IonicSpace_V1 oij d455d9a72807617634ccbf1e532b71037c45762f824ec85fcd9a4c2275562f33^B336251655E8C56B38E9E86F20E0E42E6C153785F1A0A798ADE6916E71CF055B\"\n ]\n }\n }\n ```\n *\n * so this enumerates `data.spaceIds` and gets the corresponding addrs in the `rel8ns`.\n * it then gets the space ibgibs themselves via the local zero space.\n *\n * @returns array of known local user spaces\n *\n * @throws if no local user spaces found (there should be at least one atow i think)\n */\n async getLocalUserSpaces({\n lock = false,\n }: {\n /**\n * If true, then we lock by bootstrap/spaceId before trying to retrieve.\n *\n * @default true\n */\n lock?: boolean,\n }): Promise<IbGibSpaceAny[]> {\n const lc = `${this.lc}[${this.getLocalUserSpaces.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const localSpaces: IbGibSpaceAny[] = [];\n\n // if we're not explicit with skipLock, go by platform\n // we only need to lock when doing the web, because we could\n // have multiple tabs open.\n lock ??= false;\n // if (lock === undefined) {\n // if (!this._platform) { this._platform = Capacitor.getPlatform(); }\n // if (logalot) { console.log(`${this.lc} platform: ${this._platform}`); }\n // lock = this._platform === 'web';\n // }\n\n const bootstrapIbGib =\n await getValidatedBootstrapIbGib({ zeroSpace: this.zeroSpace });\n\n // #region validate bootstrapIbGib\n if (!bootstrapIbGib) { throw new Error(`(UNEXPECTED) bootstrapIbGib falsy (E: fff2de921a3ee56a1d70e4ac320e4122)`); }\n if (!bootstrapIbGib.data) { throw new Error(`(UNEXPECTED) bootstrapIbGib data falsy (E: 7f9d08050f214078b2f85dd2ed47e005)`); }\n if (!bootstrapIbGib.data[BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY]) { throw new Error(`(UNEXPECTED) bootstrapIbGib data invalid. data[${BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY}] falsy (E: 37614e2e8f914d6ab7c605cf064a80d2)`); }\n if (bootstrapIbGib.data[BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY].length === 0) { throw new Error(`(UNEXPECTED) bootstrapIbGib data invalid. data[${BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY}] length === 0 (E: d57691d17e6b4d7ea3a8fed36c0f47e5)`); }\n // #endregion validate bootstrapIbGib\n\n const localSpaceIds = bootstrapIbGib.data[BOOTSTRAP_DATA_KNOWN_SPACE_IDS_KEY];\n\n for (let i = 0; i < localSpaceIds.length; i++) {\n const localSpaceId = localSpaceIds[i];\n if (!localSpaceId) { throw new Error(`(UNEXPECTED) localSpaceId falsy (E: 582c520897f5355d642229eae122ac22)`); }\n\n const localSpace =\n await getLocalSpace<IbGibSpaceAny>({\n zeroSpace: this.zeroSpace,\n bootstrapIbGib,\n lock,\n localSpaceId,\n callerInstanceId: this.instanceId,\n fnDtoToSpace: (spaceDto: IbGib_V1) => this.metaspaceFactory.fnDtoToSpace!(spaceDto),\n // fnDtoToSpace: (spaceDto: IbGib_V1) => {\n // return Promise.resolve(\n // NodeFilesystemSpace_V1.createFromDto(spaceDto as IbGib_V1<NodeFilesystemSpaceData_V1, NodeFilesystemSpaceRel8ns_V1>)\n // );\n // },\n localSpaceCacheSvc: this.cacheSvc,\n });\n\n localSpaces.push(localSpace);\n }\n\n return localSpaces;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n abstract get zeroSpace(): IbGibSpaceAny;\n // {\n // const lc = `${this.lc}[get zeroSpace]`;\n // if (!this._zeroSpace) { throw new Error(`this._zeroSpace falsy. should have been created on this.initialize (E: e723177fd2a74e25eb25e2299dfa4d23)`); }\n // return this._zeroSpace;\n // }\n\n // protected _localUserSpaceCurrentRoot: IbGib_V1<RootData> | undefined;\n\n /**\n * Just to prevent plaintext passwords from just sitting in memory,\n * this is a slight layer of indirection for caching.\n */\n protected passwordCache: { [addr: string]: TempCacheEntry } = {};\n\n // protected fnPromptSecret: (space: IbGibSpaceAny) => Promise<IbGib_V1 | undefined>;\n // protected fnPromptEncryption: (space: IbGibSpaceAny) => Promise<IbGib_V1 | undefined>;\n // protected fnPromptOuterSpace: (space: IbGibSpaceAny) => Promise<IbGib_V1 | undefined>;\n // protected fnPromptUpdatePic: (space: IbGibSpaceAny, picIbGib: PicIbGib_V1) => Promise<UpdatePicPromptResult | undefined>;\n // protected fnPromptUpdateComment: (space: IbGibSpaceAny, commentIbGib: CommentIbGib_V1) => Promise<UpdateCommentPromptResult | undefined>;\n // fnPromptRobbot: ((space: IbGibSpaceAny, ibGib: RobbotIbGib_V1) => Promise<RobbotPromptResult | undefined>) | undefined = undefined;\n // fnPromptApp: ((space: IbGibSpaceAny, ibGib: AppIbGib_V1) => Promise<AppPromptResult | undefined>) | undefined = undefined;\n\n protected _syncing: boolean = false;\n /**\n * should only syncIbGibs when not already syncing.\n */\n get syncing(): boolean {\n return this._syncing;\n }\n\n protected sagaInfoMap: { [sagaId: string]: SyncSagaInfo } = {};\n\n /**\n * unique set of tjp addresses that will auto sync to sync spaces.\n */\n protected _alwaysAutosyncTjpAddrsCache = new Set<TjpIbGibAddr>();\n\n // /**\n // * Cached platform value via `Capacitor.getPlatform()`.\n // */\n // protected _platform: string;\n\n /**\n * Hmm, hacky way of tracking if we're prompt the user for something.\n * We don't want to prompt while we're already prompting, and this\n * is a straight-forward approach.\n *\n * @see {@link getPasswordForSecrets}\n */\n protected isPrompting: boolean = false;\n\n // #region sync uuids\n /**\n * getUUID is async. there are many times we want a throwaway id\n * synchronously. So we'll prepopulate them here.\n */\n protected _precalculatedIds: string[] = [];\n public getUUIDSync(): string {\n const lc = `${this.lc}[${this.getUUIDSync.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const id = this._precalculatedIds.pop();\n if (!id) { throw new Error(`no precalculated ids? (E: 14915489b21d031ee9ca695737ac6923)`); }\n if (this._precalculatedIds.length < 100) {\n this.precalculateSomeUUIDsPlease(); // spins off\n // only a race condition if we're consuming sync ids\n // in a tight loop...\n }\n return id;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n async precalculateSomeUUIDsPlease(): Promise<void> {\n const lc = `${this.lc}[${this.precalculateSomeUUIDsPlease.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const ids: string[] = [];\n for (let i = 0; i < 500; i++) {\n const id = await getUUID();\n ids.push(id);\n }\n this._precalculatedIds = ids;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n async initializeObservables(): Promise<void> {\n const lc = `${this.lc}[${this.initializeObservables.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f5dc6d6352eaf2f41809ddec76ea5923)`); }\n\n // initialized\n this._initializedSubj = await newupSubject({ replay: true });\n this.initialized$ = this._initializedSubj.asObservable();\n\n // latestObs\n this._latestSubj = await newupSubject<IbGibTimelineUpdateInfo>();\n this.latestObs = this._latestSubj.asObservable();\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n // #endregion sync uuids\n\n protected metaspaceFactory: MetaspaceFactory = {};\n\n /**\n * used in alerting user of things... carryover of mvp. should be in initialize\n */\n getFnAlert: (() => (arg: { title: string, msg: string, }) => Promise<void>) | undefined;\n /**\n * used in prompting user for passwords... carryover of mvp. should be in initialize\n */\n getFnPrompt: (() => ((arg: { title: string, msg: string }) => Promise<string>)) | undefined;\n /**\n * used in prompting user for passwords... carryover of mvp. should be in initialize\n */\n getFnPromptPassword: (() => (title: string, msg: string) => Promise<string | null>) | undefined;\n\n constructor(\n protected cacheSvc: IbGibCacheService | undefined,\n ) {\n const lc = `${this.lc}[ctor]`;\n if (logalot) {\n console.log(`${lc}${GLOBAL_TIMER_NAME}`);\n console.timeLog(GLOBAL_TIMER_NAME);\n console.log(`${lc} created. (I: 5fe7af9fccc2488282eecc8255729cec)`);\n }\n }\n\n protected async initializeMetaspaceFactory({ metaspaceFactory }: { metaspaceFactory: MetaspaceFactory }): Promise<void> {\n const lc = `[${this.initializeMetaspaceFactory.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 0b84dfb68c1e89e0af880d4461fe4b23)`); }\n this.metaspaceFactory = metaspaceFactory;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async initialize({\n spaceName,\n metaspaceFactory,\n getFnAlert,\n getFnPrompt,\n getFnPromptPassword,\n }: MetaspaceInitializeOptions): Promise<void> {\n const lc = `${this.lc}[${this.initialize.name}]`;\n try {\n this.instanceId = await getUUID();\n\n if (!getFnAlert) { throw new Error(`getFnAlert required (E: c7ded289d9b6265b6d1294988faba923)`); }\n if (!getFnPrompt) { throw new Error(`getFnPrompt required (E: cce7733db0abbf9a41fa45b6b9bf9523)`); }\n if (!getFnPromptPassword) { throw new Error(`getFnPromptPassword required (E: cadae9f5df9a7c310e76b63cb6afb623)`); }\n this.getFnAlert = getFnAlert;\n this.getFnPrompt = getFnPrompt;\n this.getFnPromptPassword = getFnPromptPassword;\n\n let timerName: string = `${lc}[timer]`;\n if (logalot) {\n timerName = lc + '[timer 71cbfa]';\n console.log(`${lc} starting timer ${timerName}`);\n console.time(timerName);\n }\n\n await this.precalculateSomeUUIDsPlease();\n await this.initializeObservables();\n if (logalot) { console.timeLog(timerName); }\n await this.initializeMetaspaceFactory({ metaspaceFactory: metaspaceFactory ??= {} }); // wth is this ??= ???? no way I wrote this hmm...\n\n // local space(s)\n await this.initializeLocalSpaces({ spaceName });\n if (logalot) { console.timeLog(timerName); }\n\n // flexibility for descending classes\n await this.initializeSpecialIbGibs_required({ timerName });\n await this.initializeSpecialIbGibs_outerspaces({ timerName });\n await this.initializeSpecialIbGibs_other({ timerName });\n\n if (logalot) {\n console.timeEnd(timerName);\n console.log(`${lc} timer ${timerName} complete.`);\n }\n\n this._initialized = true;\n await this._initializedSubj!.next(ROOT);\n\n // always log when this is initialized (not just logalot)\n console.log(`${lc} initialized (I: e3b3a9652c09445cb055013166ff089c)`);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n protected async initializeSpecialIbGibs_required({ timerName }: { timerName: string }): Promise<void> {\n const lc = `[${this.initializeSpecialIbGibs_required.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8cb7f63d766ab38885dc63d8da9cd323)`); }\n\n await this.getSpecialIbGib({ type: \"latest\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"roots\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"tags\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: SpecialIbGibType.aliases, initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"robbots\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"apps\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"secrets\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"encryptions\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async initializeSpecialIbGibs_outerspaces({ timerName }: { timerName: string }): Promise<void> {\n const lc = `[${this.initializeSpecialIbGibs_outerspaces.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4f5ca25899384ceabd65e30cdf58f889)`); }\n\n await this.getSpecialIbGib({ type: \"outerspaces\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n\n await this.getSpecialIbGib({ type: \"autosyncs\", initialize: true });\n if (logalot) { console.timeLog(timerName); }\n await this.loadAutoSyncs();\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async initializeSpecialIbGibs_other({ timerName }: { timerName: string }): Promise<void> {\n const lc = `[${this.initializeSpecialIbGibs_other.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3cad0b16f5dac3686929dd1923ee3623)`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Make sure we have a bootstrapped space. This is like a node...kinda in peer\n * to peer systems.\n *\n * For all intents and purposes here to begin with, I'm using this initially\n * as where to put the settings ibGib that will contain pointers for this app, be it an\n * ionic android/web app or a browser extension. This is because the initial\n * intent of doing the spaces, besides it being necessary for the distributed\n * nature of the architecture, is to obviate the use of ionic Storage.\n * That is currently where we are storing things like the pointers to special\n * ibGibs like tags^ibgib, roots ibgibs, etc.\n */\n protected async initializeLocalSpaces({\n spaceName,\n }: {\n spaceName: string | undefined,\n }): Promise<void> {\n const lc = `${this.lc}[${this.initializeLocalSpaces.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // we're going to use the default zerospace first to find/load the actual user's space (if it exists)\n let zeroSpace = this.zeroSpace;\n if (!zeroSpace.gib) {\n zeroSpace.gib = await getGib({ ibGib: zeroSpace, hasTjp: false });\n }\n\n if (logalot) { console.log(`${lc} getting bootstrap ibgib (I: a4ad1cfd5c6f895e879d9e6a5f607b22)`); }\n // first call without locking, because we just want to see if it exists.\n // note that because of race conditions, this may be out of date though.\n const bootstrapAddr = BOOTSTRAP_IBGIB_ADDR;\n let bootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace });\n if (bootstrapIbGib) {\n // re-get it using locking to ensure we've gotten the correct one.\n if (logalot) { console.log(`${lc} getting bootstrap ibgib with locking from zero space...`) }\n bootstrapIbGib = await execInSpaceWithLocking<BootstrapIbGib>({\n space: zeroSpace,\n scope: bootstrapAddr,\n secondsValid: DEFAULT_SECONDS_VALID_LOCAL,\n fn: async () => {\n const bootstrapIbGib = await getValidatedBootstrapIbGib({ zeroSpace });\n if (!bootstrapIbGib) { throw new Error(`failed to get validated bootstrapIbGib (E: a4318a8183c3d8979981c29bd4ecb223)`); }\n return bootstrapIbGib;\n },\n callerInstanceId: this.instanceId,\n });\n if (logalot) { console.log(`${lc} got bootstrap ibgib with locking from zero space.`) }\n } else {\n if (logalot) { console.log(`${lc} getting from default space...not found. bootstrap space not found. will create... (I: 3170ac1a310d41f29f2b2b075cde6bdb)`); }\n // bootstrap space ibgib not found, so first run probably for user.\n // so create a new bootstrapGib and user space\n await this.createLocalSpaceAndUpdateBootstrap({\n zeroSpace,\n allowCancel: false,\n createBootstrap: true,\n spaceName,\n });\n }\n\n } catch (error) {\n if (logalot) { console.log(`${lc} getting from default space...not found. bootstrap space not found. (E: 617bb62c3b6c4c01a5faec7f06c719fd)`); }\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #region create functions\n\n /**\n * wrapping dispatch factory function for creating local spaces. If a factory\n * functionis provided, will use that. If not, then will use\n * this.fnDefaultLocalSpaceFactory function. Ifthat is also falsy, then this\n * will default to the NodeFSSpace factory function\n * `fnCreateNewLocalSpace_NodeFSSpace`.\n *\n * @returns newly created local space, or undefined if there was a problem.\n */\n createNewLocalSpace({\n opts,\n fnLocalSpaceFactory,\n }: {\n opts: CreateLocalSpaceOptions;\n fnLocalSpaceFactory?: LocalSpaceFactoryFunction;\n }): Promise<IbGibSpaceAny | undefined> {\n const lc = `[${this.createNewLocalSpace.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ac652df9d652459d98832be8483544d1)`); }\n if (!opts) { throw new Error(`opts required (E: f1d50207b35c96985ba6c2e1a18a4e23)`); }\n if (!opts.getFnPrompt) {\n if (logalot) { console.log(`${lc} incoming opts getFnPrompt falsy. using this.getFnPrompt (I: 1f331752ac81ffc48e2da0b27dafba23)`); }\n opts.getFnPrompt = this.getFnPrompt!;\n }\n fnLocalSpaceFactory ??= this.metaspaceFactory.fnDefaultLocalSpaceFactory;\n if (!fnLocalSpaceFactory) {\n throw new Error(`neither fnLocalSpaceFactory nor this.fnDefaultLocalSpaceFactory provided (E: 5142df9dbae63fd0ffef8165782dc423)`);\n }\n return fnLocalSpaceFactory(opts);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async createLocalSpaceAndUpdateBootstrap({\n zeroSpace,\n allowCancel,\n createBootstrap,\n spaceName,\n getFnPrompt,\n }: {\n zeroSpace: IbGibSpaceAny,\n allowCancel: boolean,\n createBootstrap: boolean,\n spaceName: string | undefined,\n getFnPrompt?: () => ((arg: { title: string, msg: string }) => Promise<string>),\n }): Promise<IbGibSpaceAny | undefined> {\n const lc = `${this.lc}[${this.createLocalSpaceAndUpdateBootstrap.name}]`;\n try {\n let newLocalSpace: IbGibSpaceAny | undefined;\n\n // first create the space\n if (allowCancel) {\n newLocalSpace = await this.createNewLocalSpace({\n opts: {\n allowCancel, spaceName, logalot, getFnPrompt: getFnPrompt ?? this.getFnPrompt!,\n },\n });\n if (!newLocalSpace) {\n // cancelled\n return undefined; /* <<<< returns early */\n }\n } else {\n // can't cancel (first run of app? not applicable i.e. testing?)\n do {\n newLocalSpace = await this.createNewLocalSpace({\n opts: {\n allowCancel, spaceName, logalot,\n getFnPrompt: getFnPrompt ?? this.getFnPrompt!,\n }\n });\n } while (!newLocalSpace)\n }\n\n // create bootstrap if needed\n // (bootstrap will be updated later in this function also)\n if (createBootstrap) {\n if (logalot) { console.log(`${lc} creating new bootstrap ibgib (I: ecc58dd4af21a0c69a16b3d71dad9c22)`); }\n await updateBootstrapIbGib({\n space: newLocalSpace,\n zeroSpace,\n setSpaceAsDefault: true,\n createIfNotFound: true,\n });\n }\n\n /**\n * this is the put arg used in both put calls to zero space and new\n * local space.\n */\n const argPutUserSpace = await zeroSpace.argy({\n ibMetadata: getSpaceArgMetadata({ space: newLocalSpace }),\n argData: {\n cmd: 'put',\n ibGibAddrs: [getIbGibAddr({ ibGib: newLocalSpace })],\n },\n ibGibs: [newLocalSpace],\n });\n\n // save the localSpace in zeroSpace\n if (logalot) { console.log(`${lc} save the localSpace in default zero space (I: 1b34fb9f548042ab9d9ae0619377e370)`); }\n const resZeroSpace = await zeroSpace.witness(argPutUserSpace);\n if (resZeroSpace?.data?.success) {\n if (logalot) { console.log(`${lc} default zero space witnessed the user space (I: b6314ea887d34609904db3bb76ae2f9b)`); }\n } else {\n throw new Error(`${resZeroSpace?.data?.errors?.join('|') || \"There was a problem with zeroSpace witnessing the new localSpace (E: b952e888a4954cc5b671034b8384e750)\"}`);\n }\n\n // save the localSpace in its own space(?)\n if (logalot) { console.log(`${lc} save the new localSpace in its own space (I: e1f520f2cc614b1fa9c1ebd1c4dd6957)`); }\n const resPutUserSpaceInUserSpace = await newLocalSpace.witness(argPutUserSpace);\n if (resPutUserSpaceInUserSpace?.data?.success) {\n // we now have saved the localSpace ibgib \"in\" its own space.\n // but atow, this does NOT change the space's gib hash, so no\n // need to update the space\n if (logalot) { console.log(`${lc} user space witnessed itself`); }\n } else {\n throw new Error(`${resPutUserSpaceInUserSpace?.data?.errors?.join('|') || \"There was a problem with localSpace witnessing itself. (E: 33d4b1ffcca64160afe67046531958b5)\"}`);\n }\n\n // update the bootstrap ibgib to point to the new local space\n await updateBootstrapIbGib({\n space: newLocalSpace,\n zeroSpace: this.zeroSpace,\n });\n\n return newLocalSpace;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n const alert = this.getFnAlert!();\n alert({ title: 'failed', msg: `failed to initialize the local space. error: ${error.message}` });\n throw error;\n }\n }\n\n async createTagIbGib({\n text,\n icon,\n description,\n space,\n }: {\n text: string,\n icon?: string,\n description?: string,\n space?: IbGibSpaceAny,\n }): Promise<{ newTagIbGib: TagIbGib_V1, newTagsAddr: string }> {\n const lc = `${this.lc}[${this.createTagIbGib.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (E: 18f846b645124210a2ff1611641a8daf)`); }\n\n return createTagIbGibAndSundry({\n text,\n icon,\n description,\n space,\n zeroSpace: this.zeroSpace,\n fnBroadcast: (x) => this.fnBroadcast(x),\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n async trash({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n }: {\n ibGib_Context: IbGib_V1,\n rel8nName_Context: IbGibAddr,\n addr: IbGibAddr,\n space?: IbGibSpaceAny,\n }): Promise<void> {\n const lc = `${this.lc}[${this.trash.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4cf73be6e3294124a78a4a45368bfbcc)`); }\n if (!ibGib_Context) { throw new Error(`ibGib_Context required (E: 09dd5e5a9f784953a42d70b1827ba442)`); }\n if (!rel8nName_Context) { throw new Error(`rel8nName_Context required (E: cb6edaaac586773b08fd18855fc11322)`); }\n if (!addr) { throw new Error(`addr required (E: 14f27805749c499098cebc0b1b11bc57)`); }\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (E: f81574e3437a4b88acd044b2abdc1ae4)`); }\n\n await trash({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n zeroSpace: this.zeroSpace,\n fnBroadcast: (x) => this.fnBroadcast(x),\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n });\n // Toast.show({ text: `trashed '${addr.slice(0, 32)}...'`, duration: \"long\" }); // spins off...\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async archive({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n }: {\n ibGib_Context: IbGib_V1,\n rel8nName_Context: IbGibAddr,\n addr: IbGibAddr,\n space?: IbGibSpaceAny,\n }): Promise<void> {\n const lc = `${this.lc}[${this.archive.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 785b44dbb7b048cb8c210a907b73b4c8)`); }\n if (!ibGib_Context) { throw new Error(`ibGib_Context required (E: dc277b47aa4f42118ad14bfc817bf1d5)`); }\n if (!rel8nName_Context) { throw new Error(`rel8nName_Context required (E: 87bd7ffa820645e9bdfb17fc726249ba)`); }\n if (!addr) { throw new Error(`addr required (E: f6ce4e1325c84aa9b3da31c5b9dcc787)`); }\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (E: d6e0b1618eec400e820de6ac37491d39)`); }\n\n await archive({\n ibGib_Context,\n rel8nName_Context,\n addr,\n space,\n zeroSpace: this.zeroSpace,\n fnBroadcast: (x) => this.fnBroadcast(x),\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n });\n\n // Toast.show({ text: `archived '${addr.slice(0, 32)}...'`, duration: \"long\" }); // spins off...\n if (logalot) { console.log(`${lc} archived '${addr.slice(0, 32)}...' (I: 767b06c8cadd58c618924f0cd98a1723)`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion\n\n /**\n * Gets a config addr from the current space via the given key\n * as the space's rel8n name.\n *\n * For example, for `key = tags`, a space may look like:\n *\n * ```json\n * {\n * ib: space xyz,\n * gib: e89ff8a1c4954db28432007615a78952,\n * rel8ns: {\n * past: [space xyz^21cb29cc353f45a491d2b49ff2f130db],\n * ancestor: [space^gib],\n * tags: [tags^99b388355f8f4a979ca30ba284d3a686], // <<< rel8n with name specified by key\n * }\n * }\n * ```\n *\n * @param key config key\n * @returns addr in config if exists, else undefined\n */\n async getConfigAddr({\n key,\n space,\n }: {\n key: string,\n space?: IbGibSpaceAny,\n }): Promise<string | undefined> {\n const lc = `${this.lc}[${this.getConfigAddr.name}](${key})`;\n try {\n if (logalot) { console.log(`${lc} getting...`) }\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and could not get local space. (E: b6e7fcc09c6244b99b2e6e6ece398db0)`); }\n\n return getConfigAddr({ key, space });\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n }\n\n fnUpdateBootstrap = async (newSpace: IbGibSpaceAny) => {\n // const space = await this.getLocalUserSpace({}); // cruft/wasted call?\n await updateBootstrapIbGib({ space: newSpace, zeroSpace: this.zeroSpace });\n }\n\n fnBroadcast = (info: IbGibTimelineUpdateInfo) => {\n // if (!getIbAndGib({ibGibAddr: info.latestAddr}).gib?.includes('.')) {\n // need to know why tjp's continue to get published as the latest addrs\n // }\n // this._latestSubj.next({tjpAddr, latestAddr: ibGibAddr, latestIbGib: ibGib});\n // let gib = getIbAndGib({ibGibAddr: info.latestAddr}).gib;\n this._latestSubj!.next(info); // spins off\n }\n\n /**\n * Takes the given `key`, which should be unique in the given space (or\n * zerospace), and uses that to persist the given `addr` in that space.\n *\n * # notes\n *\n * configuration is stored in \"special\" ibgibs, and so we need only to persist\n * the address of that configuration.\n */\n async setConfigAddr({\n key,\n addr,\n space,\n }: {\n key: string,\n addr: string,\n space?: IbGibSpaceAny,\n }): Promise<IbGibSpaceAny> {\n const lc = `${this.lc}[${this.setConfigAddr.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: 2149c59ebd584a118304dd54656aa800)`); }\n\n return await setConfigAddr({\n key, addr, space, zeroSpace: this.zeroSpace,\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n });\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n async getCurrentRoot({\n space,\n }: {\n space?: IbGibSpaceAny,\n }): Promise<IbGib_V1<RootData> | undefined> {\n const lc = `${this.lc}[${this.getCurrentRoot.name}]`;\n\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: 1f4dc5e9560341a993bf0b28accd75fe)`); }\n\n while (this.initializing) {\n if (logalot) { console.log(`${lc} hacky wait while initializing ibgibs service (I: 5fd759510e584cb69b232259b891cca1)`); }\n await delay(100);\n }\n const roots = await this.getSpecialIbGib({ type: \"roots\", space });\n if (!roots) { throw new Error(`Roots not initialized. (E: e7712dc3d183487e98cd44a2b4324bc2)`); }\n if (!roots.rel8ns) { throw new Error(`Roots not initialized properly. No rel8ns. (E: 689f47f5d1da4a868d1c1ddd2ff13e17)`); }\n if (!roots.rel8ns.current) { throw new Error(`Roots not initialized properly. No current root. (E: 962acd3f60474a329bfbd7682c003916)`); }\n if (roots.rel8ns.current.length === 0) { throw new Error(`Invalid Roots: empty current root rel8n. (E: fbdc13c157514efa86ade1bf9a38bbd6)`); }\n if (roots.rel8ns.current.length > 1) { throw new Error(`Invalid Roots: multiple current roots selected. (E: 370fe6e3920a4a1299f879e6fcbbc448)`); }\n\n const currentRootAddr = roots.rel8ns.current[0]!;\n const resCurrentRoot =\n await this.get({ addr: currentRootAddr, space });\n if (resCurrentRoot.ibGibs?.length === 1) {\n return resCurrentRoot.ibGibs![0] as IbGib_V1<RootData>;\n } else {\n throw new Error(`could not get current root. addr: ${currentRootAddr} (E: 69de35c5f71e45a1a5d83228e136642b)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n }\n\n async setCurrentRoot({\n root,\n space,\n }: {\n root: IbGib_V1<RootData>,\n space?: IbGibSpaceAny,\n }): Promise<void> {\n const lc = `${this.lc}[${this.setCurrentRoot.name}]`;\n try {\n if (!root) { throw new Error(`root required.`); }\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: 222a3f5b39fc47ccb2a4aa3ddcd49969)`); }\n\n return setCurrentRoot({\n root,\n space,\n zeroSpace: this.zeroSpace,\n fnBroadcast: (x) => this.fnBroadcast(x),\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n });\n\n // how to let others know roots has changed?\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Every tjp should be related to one of the roots in a space.\n *\n * You should NOT relate every ibgib frame of a given ibGib.\n */\n async rel8ToCurrentRoot({\n ibGib,\n linked,\n rel8nName,\n space,\n }: {\n ibGib: IbGib_V1,\n linked?: boolean,\n rel8nName?: string,\n space?: IbGibSpaceAny,\n }): Promise<void> {\n const lc = `${this.lc}[${this.rel8ToCurrentRoot.name}]`;\n\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: cbc4e519414a405eab7fe470eadbf8f0)`); }\n\n return rel8ToCurrentRoot({\n ibGib,\n linked,\n rel8nName,\n space,\n zeroSpace: this.zeroSpace,\n fnBroadcast: (x) => this.fnBroadcast(x),\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return;\n }\n }\n\n /**\n * rel8s given ibgibs to special ibgib.\n * @see {@link rel8ToSpecialIbGib}\n * @returns new special ibgib addr\n */\n async rel8ToSpecialIbGib(opts: {\n type: SpecialIbGibType,\n rel8nName: string,\n /**\n * multiple ibgibs to rel8\n */\n ibGibsToRel8?: IbGib_V1[],\n /**\n * multiple ibgibs to UNrel8.\n * YOU CANNOT SET BOTH {@link ibGibsToUnRel8} AND {@link addrsToUnRel8}\n * There is no technical reason for this, I'm just too tired to implement\n * yagni overhead.\n * @see {@link addrsToUnRel8}\n */\n ibGibsToUnRel8?: IbGib_V1[],\n /**\n * alternatively just specify addrs to unrel8.\n * YOU CANNOT SET BOTH {@link ibGibsToUnRel8} AND {@link addrsToUnRel8}\n * There is no technical reason for this, I'm just too tired to implement\n * yagni overhead.\n * @see {@link ibGibsToUnRel8}\n */\n addrsToUnRel8?: IbGibAddr[],\n linked?: boolean,\n /**\n * Clears out the special.rel8ns.past array to an empty array.\n *\n * {@see deletePreviousSpecialIbGib} for driving use case.\n */\n severPast?: boolean,\n /**\n * Deletes the previous special ibGib.\n *\n * ## driving use case\n *\n * the latest ibGib is one that is completely ephemeral. It doesn't get attached\n * to the current root, and it only has the current instance. So we don't want to\n * keep around past incarnations.\n */\n deletePreviousSpecialIbGib?: boolean,\n space?: IbGibSpaceAny,\n }): Promise<IbGibAddr> {\n const lc = `${this.lc}[${this.rel8ToSpecialIbGib.name}](type:${opts.type},rel8nName:${opts.rel8nName})`;\n try {\n let {\n type,\n rel8nName,\n ibGibsToRel8,\n ibGibsToUnRel8,\n addrsToUnRel8,\n linked,\n severPast,\n deletePreviousSpecialIbGib,\n space,\n } = opts;\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: af863928bbc945549ffc4dcca830a70a)`); }\n\n // return rel8ToSpecialIbGib({\n // type,\n // rel8nName,\n // ibGibsToRel8,\n // ibGibsToUnRel8,\n // linked,\n // severPast,\n // deletePreviousSpecialIbGib,\n // space,\n // zeroSpace: this.zeroSpace,\n // fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n // fnBroadcast: (x) => this.fnBroadcast(x),\n // });\n // note: 05/2025, I had added addrsToUnRel8 to signature but didn't do this maintenance and wasted a few hours debugging this. So changing this to spread with opts so we don't have to change this if we do this again. need to keep an eye out for this in the future (personally)\n return rel8ToSpecialIbGib({\n ...opts,\n space,\n zeroSpace: this.zeroSpace,\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n fnBroadcast: (x) => this.fnBroadcast(x),\n });\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Used for tracking tjpAddr -> latest ibGibAddr.\n *\n * Call this when you create a new ibGib.\n *\n * Need to put this in another service at some point, but crunch crunch\n * like pacman's lunch.\n */\n async registerNewIbGib({\n ibGib,\n space,\n }: {\n ibGib: IbGib_V1,\n space?: IbGibSpaceAny,\n }): Promise<void> {\n let lc = `${this.lc}[${this.registerNewIbGib.name}]`;\n try {\n const ibGibAddr: IbGibAddr = getIbGibAddr({ ibGib });\n lc = `${lc}[${ibGibAddr}]`;\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: d7e6d609a784449087cbaf1bbfb6b0c2)`); }\n\n if (logalot) { console.log(`${lc} starting...`); }\n\n return registerNewIbGib({\n ibGib,\n space,\n fnBroadcast: (x) => this.fnBroadcast(x),\n });\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Will trigger a latest info event to be fired.\n * @param param0\n */\n async pingLatest_Local({\n ibGib,\n tjpIbGib,\n space,\n useCache,\n }: {\n ibGib: IbGib_V1<any>,\n tjpIbGib: IbGib_V1<any> | undefined,\n space?: IbGibSpaceAny,\n /**\n * If true, then will check the latest ibgib cache first. if found, will\n * just return that.\n */\n useCache: boolean,\n }): Promise<void> {\n let lc = `${this.lc}[${this.pingLatest_Local.name}]`;\n if (logalot) { console.log(`${lc} starting...`); }\n try {\n if (!ibGib) {\n if (logalot) { console.log(`${lc} ibGib falsy.`); }\n return; /* <<<< returns early */\n }\n if (isPrimitive({ ibGib })) {\n console.warn(`${lc} tried to ping latest for primitive. returning early... (W: 06c50cfe028cc04cca67e97a48e6fe22)`);\n return; /* <<<< returns early */\n }\n\n if (ibGib.ib.startsWith(`witness space IonicSpace_V1`)) {\n // pinging a local user space, which for better or worse, does not\n // have a tjp (nor is it kept up to date via the latest index).\n // I can't remember, but I think there was a reason for the last bit,\n // but I probably should have given it a tjp. Anyway, the latest\n // \"index\" for local spaces is in the bootstrap. (Also the space is\n // not necessarily contained in the passed in `space` arg.)\n const { spaceId } = parseSpaceIb({ spaceIb: ibGib.ib });\n const latestSpace =\n await this.getLocalUserSpace({ localSpaceId: spaceId });\n // if (latestSpace.gib !== ibGib.gib) { // leavin this in for now. delete after awhile of normal operation. see https://github.com/wraiford/ibgib/commit/2247235a6f25945000fef419c08d5518ba2cfb48\n await this._latestSubj!.next({\n ib: 'IbGibTimelineUpdateInfo',\n latestIbGib: latestSpace,\n latestAddr: getIbGibAddr({ ibGib: latestSpace }),\n tjpAddr: `${ibGib.ib}^gib`\n });\n // }\n return; /* <<<< returns early */\n }\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) {\n console.warn(`${lc} space falsy and localUserSpace not initialized. (W: e6708e58618947a6b66f6a49406cbf35)`);\n return;\n }\n\n let latestIbGib: IbGib_V1;\n let ibGibAddr = getIbGibAddr({ ibGib });\n let tjpAddr: IbGibAddr;\n\n // if (!latestIbGib || !latestAddr) {\n // not found in cache or caller didn't allow using the cache\n let latestAddr = await this.getLatestAddr({ ibGib, tjp: tjpIbGib, space }) ?? ibGibAddr;\n\n // get the tjp for the rel8nName mapping, and also for some checking logic\n if (!tjpIbGib) {\n tjpIbGib = await this.getTjpIbGib({ ibGib, space });\n if (!tjpIbGib) {\n console.warn(`${lc} tjp not found for ${ibGibAddr}? Should at least just be the ibGib's address itself. (W: 15d9c6daca7e442e968af36b4c18b8f7)`);\n tjpIbGib = ibGib;\n }\n }\n tjpAddr = getIbGibAddr({ ibGib: tjpIbGib });\n\n if (latestAddr === ibGibAddr) {\n if (logalot) { console.log(`${lc} latestAddr === ibGibAddr (I: f38042421fcc3d148a26ed56651c2522)`); }\n latestIbGib = ibGib;\n } else {\n if (logalot) { console.log(`${lc} later version found. ibGibAddr: ${ibGibAddr}\\nlatestAddr: ${latestAddr} (I: 53cabd1643df7d43635af642e4c90922)`); }\n let resLatestIbGib = await this.get({ addr: latestAddr, space });\n if (!resLatestIbGib.success || resLatestIbGib.ibGibs?.length !== 1) { throw new Error(`latest not found (E: bc54e433573a5a89c6436dc6a3b60922)`); }\n latestIbGib = resLatestIbGib.ibGibs![0];\n\n // if (useCache) {\n // // we tried to use cache but it wasn't there, so put it for the next time.\n // if (logalot) { console.log(`${lc} putting in getLatest cache (I: 5f264edf03940a0f7e72252fd6fe0d22)`); }\n // console.log(`${lc} putting in getLatest cache (I: 5f264edf03940a0f7e72252fd6fe0d22)`);\n // setTimeout(async () => {\n // await this.latestCacheSvc.put({\n // addr: latestAddr,\n // ibGib: latestIbGib,\n // tjpAddr,\n // tjpIbGib: tjpIbGib,\n // });\n // }, Math.ceil(Math.random() * 10000));\n // }\n }\n // }\n\n if (latestIbGib && latestAddr && tjpAddr) {\n await this._latestSubj!.next({\n ib: 'IbGibTimelineUpdateInfo',\n latestIbGib,\n latestAddr,\n tjpAddr\n });\n } else {\n debugger; // before error\n throw new Error(`(UNEXPECTED) latestIbGib, latestAddr and tjpAddr should all be truthy. (E: 20e71fa1a72c45deb1dc5083903a8622)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #region space facade (e.g. get, getLatest___, put, etc.)\n\n /**\n * Convenience function for persisting a transform result, which has\n * a newIbGib and optionally intermediate ibGibs and/or dnas.\n *\n * it persists these ibgibs into the given space, else the current space.\n */\n async persistTransformResult({\n resTransform,\n force,\n space,\n }: {\n resTransform: TransformResult<IbGib_V1>,\n force?: boolean,\n space?: IbGibSpaceAny,\n }): Promise<void> {\n const lc = `${this.lc}[${this.persistTransformResult.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: f8b3d06006874b479240eb45f4015628)`); }\n\n return persistTransformResult({\n resTransform,\n force,\n space,\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Wrapper for retrieving ibgib from a given space, else the current space.\n */\n async get({\n addr,\n addrs,\n isDna,\n space,\n }: GetIbGibOpts): Promise<GetIbGibResult> {\n let lc = `${this.lc}[${this.get.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: 86ccdcf3417a45b4a3a8c280fb9a6df7)`); }\n\n return getFromSpace({ addr, addrs, isDna, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return Promise.resolve({ errorMsg: error.message });\n }\n }\n\n /**\n * Wrapper for saving ibgib in a given space, else the current space.\n */\n async put({\n ibGib,\n ibGibs,\n isDna,\n force,\n space,\n }: PutIbGibOpts): Promise<PutIbGibResult> {\n const lc = `${this.lc}[${this.put.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: a00eebe0e3d348d09fda62a6be486b6c)`); }\n\n return putInSpace({ ibGib, ibGibs, isDna, force, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return Promise.resolve({ errorMsg: error.message });\n }\n }\n\n /**\n * Wrapper for removing ibgib from the a given space, else the current space.\n */\n async delete({\n addr,\n isDna,\n space,\n }: DeleteIbGibOpts): Promise<DeleteIbGibResult> {\n const lc = `${this.lc}[${this.delete.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: b4250b0045dc40629447f2cbd162faaa)`); }\n\n return deleteFromSpace({ addr, isDna, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return Promise.resolve({ errorMsg: error.message });\n }\n }\n\n /**\n * Wrapper for `getDependencyGraph` fn in `helper/space.ts`, but using\n * `this.localUserSpace` as default space.\n *\n * (refactoring!)\n *\n * ## note on space\n *\n * pass in `null` for space if you want to\n *\n * ## warning\n *\n * This does not (YET) have a flag that gets the latest ibgibs for the graph.\n * It only climbs the current graph, which may not cover all ibgibs when you\n * deal with ibGibs with tjps (timelines). We're going to eventually\n * combat this with auto-updating our rel8ns, but for now we're just going\n * to earmark this for the future.\n *\n * todo: auto-update or better\n *\n * @returns map of addr => ibGib\n */\n async getDependencyGraph(opts: GetDependencyGraphOptions): Promise<{ [addr: string]: IbGib_V1 }> {\n const lc = `${this.lc}[${this.getDependencyGraph.name}]`;\n try {\n opts.space = opts.space ?? await this.getLocalUserSpace({}) ?? null;\n if (!opts.space) { throw new Error(`(UNEXPECTED) space falsy and localUserSpace not initialized (?) (E: e2a35a23d12d48ebadcfd4f1a396d6c1)`); }\n\n return getDependencyGraph(opts);\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Wrapper for getting the latest addr in the given space.\n *\n * ## warnings\n *\n * * This was written early and makes many assumptions.\n * * Meant to work with Ionic space atow.\n *\n * @returns latest addr in a given space (or localUserSpace) or undefined if does not exist\n */\n async getLatestAddr({\n ibGib,\n addr,\n tjpAddr,\n tjp,\n space,\n }: {\n ibGib?: IbGib_V1<any>,\n addr?: IbGibAddr,\n tjpAddr?: IbGibAddr,\n tjp?: IbGib_V1<any>,\n space?: IbGibSpaceAny,\n }): Promise<IbGibAddr | undefined> {\n let lc = `${this.lc}[${this.getLatestAddr.name}]`;\n if (logalot) { console.log(`${lc} starting...`); }\n try {\n if (!ibGib && !tjp && !tjpAddr && !addr) {\n throw new Error(`ibGib && tjp && tjpAddr && addr are all falsy (E: fe725654342c4d80a33219160b5d81d3)`);\n }\n\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: fd01bb85e91f4c54bfe8b35714d48a38)`); }\n\n const resGetLatest = await getLatestAddrs({\n ibGibs: ibGib ? [ibGib] : undefined,\n addrs: addr ? [addr] : undefined,\n tjpAddrs: tjpAddr ? [tjpAddr] : undefined,\n tjps: tjp ? [tjp] : undefined,\n space,\n });\n\n if (!resGetLatest) { throw new Error(`resGetLatest falsy (E: 3851bbe4427ae11771f222234e8c6622)`); }\n if (!resGetLatest.data) { throw new Error(`invalid resGetLatest: data falsy (E: 134e0f1f65edc69c6951c32e00a4bb22)`); }\n if (resGetLatest.data.success) {\n // Should have addrs map\n const latestAddrsMap = resGetLatest.data.latestAddrsMap;\n if (!latestAddrsMap) {\n // fallback to old way just in case? Or just error.\n // The error I saw had latestAddrsMap but no addrs.\n // So we should look at the map.\n if (resGetLatest.data.addrs?.length === 1) {\n return resGetLatest.data.addrs[0];\n } else if (resGetLatest.data.addrsNotFound?.length === 1) {\n return undefined;\n }\n } else {\n // We have the map. Ideally we want the one entry.\n const keys = Object.keys(latestAddrsMap);\n if (keys.length === 1) {\n return latestAddrsMap[keys[0]] || undefined;\n } else if (keys.length === 0) {\n // could be not found?\n if (resGetLatest.data.addrsNotFound?.length === 1) {\n return undefined;\n } else {\n // If we didn't find it, and success is true, maybe it's just undefined?\n // But usually getLatestAddrs returns map entries for found ones.\n return undefined;\n }\n } else {\n throw new Error(`(UNEXPECTED) latestAddrsMap has multiple entries? We only asked for one. (E: 790518290f6b46729017684698539222)`);\n }\n }\n\n if (resGetLatest.data.addrsErrored?.length === 1) {\n const emsg = resGetLatest.data.errors?.join('|') ?? \"[unspecified error(s)] (E: 24f338036aa84ac99e3c39a660207222)\";\n throw new Error(`resGetLatest had error(s): ${emsg}`);\n } else {\n throw new Error(`unknown error, invalid resGetLatest: ${pretty(resGetLatest)} (E: 6aa5aa225ebf49b588664370cb8feb22)`);\n }\n } else {\n const emsg = resGetLatest.data.errors?.join('|') ?? \"[unspecified error(s)] (E: dcd6dcd6ec052fd112a4d48f1afa2922)\";\n throw new Error(`resGetLatest had error(s): ${emsg}`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Gets the tjpIbGib for the given `ibGib` in the given `space`.\n * atow, naive must be true.\n *\n *\n *\n * @returns tjpIbGib for the given `ibGib`\n */\n async getTjpIbGib({\n ibGib,\n naive = true,\n space,\n }: {\n ibGib: IbGib_V1<any>,\n naive?: boolean,\n space?: IbGibSpaceAny,\n }): Promise<IbGib_V1<any> | undefined> {\n const lc = `${this.lc}[${this.getTjpIbGib.name}]`;\n\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: 0ec806bd2c5641c4844a3698c922e1f6)`); }\n if (!space) {\n console.warn(`${lc} space falsy and localUserSpace not initialized.`);\n return ibGib;\n }\n return getTjpIbGib({ ibGib, naive, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Gets one of the app's special ibGibs, e.g., TagsIbGib.\n *\n * When initializing tags, this will generate some boilerplate tags.\n * I'm going to be doing roots here also, and who knows what else, but each\n * one will have its own initialize specifics.\n *\n * @param initialize initialize (i.e. create) ONLY IF IbGib not found. Used for initializing app (first run).\n *\n * @see {@link createSpecial}\n * @see {@link createTags}\n */\n async getSpecialIbGib({\n type,\n initialize,\n space,\n lock,\n dontWarnIfNotExist,\n }: {\n type: SpecialIbGibType,\n initialize?: boolean,\n space?: IbGibSpaceAny,\n lock?: boolean,\n /**\n * if true, won't warn about non-existent/non-initialized things.\n * useful if you are just checking to see if a special ibgib exists.\n */\n dontWarnIfNotExist?: boolean,\n }): Promise<IbGib_V1 | null> {\n const lc = `${this.lc}[${this.getSpecialIbGib.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({ lock });\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: e08e85d8422e479f9d101194fd26cbda)`); }\n\n while (this.initializing) {\n if (logalot) { console.log(`${lc} hacky wait while initializing ibgibs service (I: 497d4becb94f4515a2ec389630420d6c)`); }\n await delay(100);\n }\n\n return getSpecialIbGib({\n type,\n initialize,\n space,\n zeroSpace: this.zeroSpace,\n fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n fnBroadcast: (x) => this.fnBroadcast(x),\n fnGetInitializing: () => { return this._initializing; },\n fnSetInitializing: (value: boolean) => { this._initializing = value; },\n dontWarnIfNotExist,\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return null;\n }\n }\n\n async getSpecialRel8dIbGibs<TIbGib extends IbGib_V1 = IbGib_V1>({\n type,\n rel8nName,\n space,\n }: {\n type: SpecialIbGibType,\n rel8nName: string,\n space?: IbGibSpaceAny,\n }): Promise<TIbGib[]> {\n const lc = `${this.lc}[${this.getSpecialRel8dIbGibs.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: 476c7d7c68f34197b740be5df09238a2)`); }\n\n return getSpecialRel8dIbGibs({ type, rel8nName, space });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n // #endregion space facade (e.g. get, getLatest___, put, etc.)\n\n /**\n * Feels klugy.\n */\n async getPasswordForSecrets({\n secretIbGibs,\n fnPromptPassword,\n dontPrompt,\n checkCacheFirst,\n cacheAfter,\n }: {\n secretIbGibs: IbGib_V1<SecretData_V1>[],\n fnPromptPassword: (title: string, msg: string) => Promise<string | null>,\n /**\n * i think this was added because I didn't want it prompting in the\n * background in case we were trying to sync in the background and the\n * user hadn't entered the password (and cached it).\n */\n dontPrompt?: boolean,\n checkCacheFirst?: boolean,\n cacheAfter?: boolean,\n }): Promise<string | null> {\n const lc = `${this.lc}[${this.getPasswordForSecrets.name}]`;\n /** Flag that we'll check in finally clause */\n let erroredDueToPromptTimeout = false;\n try {\n let tries = 0;\n while (this.isPrompting) {\n if (logalot) { console.log(`${lc} hacky wait while already prompting (I: 852007c8549d42c096defe0105b5e2e6)`); }\n await delay(100);\n tries++;\n if (tries > 1000) {\n erroredDueToPromptTimeout = true;\n throw new Error(`attempted to prompt for user password, but already prompting for quite awhile now. (E: 8bd4dc907422dd95862b2038ffe2b822)`);\n }\n }\n\n\n // used if we `checkCacheFirst` AND/OR if we `cacheAfter`\n const secretsCacheKey =\n secretIbGibs.map(ibGib => getIbGibAddr({ ibGib })).join('');\n\n if (checkCacheFirst) {\n const cachedPassword =\n await this.getCachedSecretPassword({ cacheKey: secretsCacheKey });\n\n if (cachedPassword) {\n // do NOT log the actual cachedPassword!!\n if (logalot) { console.log(`${lc} using cachedPassword.`); }\n return cachedPassword;\n }\n }\n\n if (dontPrompt) {\n return null; /* <<<< returns early */\n }\n\n // build prompt message\n this.isPrompting = true;\n\n let secretInfos: SecretInfo_Password[] = [];\n for (let i = 0; i < secretIbGibs.length; i++) {\n const secretIbGib = secretIbGibs[i];\n if (!secretIbGib.data) { throw new Error(`invalid secretIbGib. data falsy.`); }\n if (secretIbGib.data!.type === 'password') {\n const secretInfo = secretIbGib.data as SecretInfo_Password;\n secretInfos.push(secretInfo);\n } else {\n throw new Error(`Only password secrets are implemented atm.`);\n }\n }\n const separator = '-------------';\n const secretInfosMsgBlock = secretInfos.map(secretInfo => {\n return `name: ${secretInfo.name}\n description: ${secretInfo.description}\n hint: ${secretInfo.hint}`;\n }).join('\\n' + separator + '\\n');\n\n // prompt user\n const title = `Gimme a password.`;\n const msg =\n `Enter the password corresponding to the following secret(s):\\n\n ${separator}\\n\\n\n ${secretInfosMsgBlock}\n `;\n let password = await fnPromptPassword(title, msg);\n\n // cache if applicable\n if (password && cacheAfter) {\n await this.setCachedSecretPassword({\n cacheKey: secretsCacheKey,\n secretPassword: password,\n });\n }\n\n // we're done\n return password;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (!erroredDueToPromptTimeout) {\n // if we errored due to prompt timeout, then some other call to this\n // function is prompting and we don't want to turn off their flag.\n this.isPrompting = false;\n }\n }\n }\n\n /**\n * creates a ciphertext ibgib (stone) based on the given plaintext.\n */\n async getCiphertextIbGib<TEncryptionIbGib extends IbGib_V1<EncryptionData_V1>, TMetadata = any>({\n plaintext,\n password,\n encryptionIbGib,\n confirm,\n persist,\n ibRoot,\n publicIbMetadata,\n publicMetadata,\n }: {\n /**\n * Um...data...to...erm...encrypt...(as a string)\n */\n plaintext: string,\n /**\n * Password to perform the encryption.\n */\n password: string,\n /**\n * Information about encryption, i.e. encryption settings.\n */\n encryptionIbGib: TEncryptionIbGib,\n /**\n * Confirms encryption succeeds by doing an immediate decrypt and checking against original data.\n */\n confirm?: boolean,\n /**\n * If true, will persist the ibgib\n */\n persist?: boolean,\n /**\n * If you provide this, the resulting ibgib will have the following format:\n * `${ibRoot} ${publicIbMetadata}`. Otherwise, this will default to:\n * `ciphertext ${publicIbMetadata}`, or just `ciphertext` if\n * `publicIbMetadata` is falsy.\n */\n ibRoot?: string,\n /**\n * If you want to include metadata in the ib itself of the\n * ciphertext ibgib. This will of course make this metadata\n * available without loading the full ibgib, but will increase\n * storage size because every address linking to the ibgib will\n * include this as well.\n */\n publicIbMetadata?: string,\n /**\n * If you want to include public, unencrypted metadata in the ibgib's\n * data body itself.\n */\n publicMetadata?: TMetadata,\n }): Promise<TransformResult<CiphertextIbGib_V1>> {\n const lc = `${this.lc}[${this.getCiphertextIbGib.name}]`;\n try {\n const encryptionInfo = encryptionIbGib.data;\n if (encryptionInfo?.method !== EncryptionMethod.encrypt_gib) {\n throw new Error('only encrypt-gib is implemented. (E: 1d8eb1be6d3f44f0a79b498f237147e6');\n }\n const info: EncryptionInfo_EncryptGib = encryptionInfo;\n const resEncrypt = await encrypt({\n dataToEncrypt: plaintext,\n secret: password,\n initialRecursions: info.initialRecursions,\n recursionsPerHash: info.recursionsPerHash,\n salt: info.salt,\n saltStrategy: info.saltStrategy,\n hashAlgorithm: info.hashAlgorithm,\n encryptedDataDelimiter: info.encryptedDataDelimiter,\n blockMode: encryptionInfo.blockMode ? encryptionInfo.blockModeOptions : undefined,\n indexingMode: encryptionInfo.indexingMode,\n confirm,\n });\n\n if (resEncrypt.warnings?.length ?? 0 > 0) { console.warn(`${lc} warnings: ${resEncrypt.warnings!.join('\\n')}`); }\n if (resEncrypt.errors?.length ?? 0 > 0) { throw new Error(resEncrypt.errors!.join('\\n')); }\n if (!resEncrypt.encryptedData) { throw new Error(`encryptedData is falsy`) }\n\n const data: CiphertextData = {\n ciphertext: resEncrypt.encryptedData,\n uuid: await getUUID(),\n };\n if (publicMetadata) { data.metadata = publicMetadata; }\n\n const ciphertextIbGib = await constantIbGib<CiphertextData, CiphertextRel8ns>({\n parentPrimitiveIb: ibRoot || CIPHERTEXT_ATOM,\n ib:\n publicIbMetadata ?\n `${ibRoot || CIPHERTEXT_ATOM} ${publicIbMetadata}` :\n `${ibRoot || CIPHERTEXT_ATOM}`,\n data,\n rel8ns: undefined,\n }) as CiphertextIbGib_V1;\n const resTransform: TransformResult<CiphertextIbGib_V1> = {\n newIbGib: ciphertextIbGib\n }\n\n if (persist) {\n await this.persistTransformResult({ resTransform });\n }\n\n return resTransform;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Brings together a ciphertext and secretIbGibs to decrypt\n * the `ciphertextIbGib.data.ciphertext`\n * @returns plaintext string of `ciphertextIbGib.data.ciphertext`\n */\n async getPlaintextString({\n ciphertextIbGib,\n secretIbGibs,\n fnPromptPassword,\n dontPrompt,\n space,\n }: {\n ciphertextIbGib: CiphertextIbGib_V1,\n secretIbGibs: SecretIbGib_V1[],\n fnPromptPassword: (title: string, msg: string) => Promise<string | null>,\n dontPrompt?: boolean,\n space: IbGibSpaceAny,\n }): Promise<string> {\n const lc = `${this.lc}[${this.getPlaintextString.name}]`;\n try {\n // validate\n if ((secretIbGibs || []).length === 0) { throw new Error(`secretIbGibs required. (E: 99a605b540c54b6db4d2ffe2caeb226a)`); }\n if (!ciphertextIbGib.data) { throw new Error(`ciphertextIbGib.data falsy (E: 598fc6473149e240a7d6916ecf642323)`); }\n if (!ciphertextIbGib.data.ciphertext) { throw new Error(`ciphertextIbGib.data.ciphertext falsy (E: 0e764a71ec214132a5a528f17f495a7c)`); }\n if (!ciphertextIbGib.rel8ns?.encryption) { throw new Error(`ciphertextIbGib.rel8ns.encryption falsy (E: a0b4d5d8674b4d0191fa619164153022)`) }\n if (ciphertextIbGib.rel8ns!.encryption!.length !== 1) { throw new Error(`ciphertextIbGib.rel8ns!.encryption!.length !== 1 (E: a4a463e1ef0e45b4917eb04cb40d8173)`); }\n\n // get corresponding encryption ibgib for encryption settings\n const encryptionAddr = ciphertextIbGib.rel8ns!.encryption![0];\n const resEncryption = await this.get({ addr: encryptionAddr, space });\n if (!resEncryption.success) { throw new Error(`get encryption failed (E: feef34c05fae439c81ade7fc23037af1)`); }\n if ((resEncryption.ibGibs || []).length !== 1) { throw new Error(`get encryption retrieved non-1 length (eesh) (E: 5d7e2023cc2b4e349574c17d5cfc8867)`); }\n const encryptionIbGib = resEncryption.ibGibs![0] as IbGib_V1<EncryptionData_V1>;\n if (!encryptionIbGib.data) { throw new Error(`encryptionIbGib.data falsy (E: 409a243afbf24c20987524f6588816fa)`); }\n\n // prompt user for the password\n const password = await this.getPasswordForSecrets({\n secretIbGibs,\n fnPromptPassword,\n dontPrompt,\n checkCacheFirst: true,\n cacheAfter: true,\n });\n\n // we're about the decrypt, but maybe the data doesn't have everything.\n // So WARN for any defaults we're using.\n if (!encryptionIbGib.data.initialRecursions) { console.warn(`${lc} using default initialRecursions because encryptionIbGib does not state this explicitly (W: 66774cbfccd44423949d34167da6d50b)`); }\n if (!encryptionIbGib.data.recursionsPerHash) { console.warn(`${lc} using default recursionsPerHash because encryptionIbGib does not state this explicitly (W: 29e264094f384d259319ba8587cd4f63)`); }\n if (!encryptionIbGib.data.saltStrategy) { console.warn(`${lc} using default saltStrategy because encryptionIbGib does not state this explicitly (W: 7a5acadb8d634c7e87f62c86b57ac7a2)`); }\n if (!encryptionIbGib.data.hashAlgorithm) { console.warn(`${lc} using default hashAlgorithm because encryptionIbGib does not state this explicitly(W: 2254db3569534b239a8c471b700c8500)`); }\n\n const defaultIndexingMode = encryptionIbGib.data.blockMode ?\n DEFAULT_ALPHABET_INDEXING_MODE_BLOCKMODE :\n DEFAULT_ALPHABET_INDEXING_MODE_LEGACY;\n if (encryptionIbGib.data.blockMode) {\n if (!encryptionIbGib.data.blockModeOptions) { throw new Error(`invalid encryptionIbGib.data. blockMode is truthy but blockModeOptions is falsy. (E: 84bbc27a5248b7c4734a1674e41dd224)`); }\n if (!encryptionIbGib.data.indexingMode) {\n console.warn(`${lc} not complete. using default indexingMode ${defaultIndexingMode} because encryptionIbGib does not state this explicitly. (W: c15797cd8d0740ea886a348c10be2e5c)`)\n }\n }\n\n // do actual decryption\n if (logalot) { console.log(`${lc} starting decrypt... (I: e14176ebc9a7470fb977d2184f1e2430)`); }\n const timerName = 'sync_log decrypt';\n console.time(timerName);\n console.timeLog(timerName, 'decrypting...');\n const resDecrypt = await decrypt({\n encryptedData: ciphertextIbGib.data.ciphertext,\n secret: password ?? '',\n initialRecursions:\n encryptionIbGib.data.initialRecursions || DEFAULT_ENCRYPTION_INITIAL_RECURSIONS,\n recursionsPerHash:\n encryptionIbGib.data.recursionsPerHash || DEFAULT_ENCRYPTION_RECURSIONS_PER_HASH,\n salt: encryptionIbGib.data.salt,\n saltStrategy:\n encryptionIbGib.data.saltStrategy || DEFAULT_ENCRYPTION_SALT_STRATEGY,\n hashAlgorithm:\n encryptionIbGib.data.hashAlgorithm || DEFAULT_ENCRYPTION_HASH_ALGORITHM,\n encryptedDataDelimiter: encryptionIbGib.data.encryptedDataDelimiter,\n blockMode: encryptionIbGib.data.blockMode ? encryptionIbGib.data.blockModeOptions! : undefined,\n indexingMode: encryptionIbGib.data.indexingMode || defaultIndexingMode,\n });\n console.timeLog(timerName, 'decrypting complete.');\n console.timeEnd(timerName);\n if (logalot) { console.log(`${lc} decrypt complete. (I: 15a8182230294a8a96504ba3667f039a)`); }\n if (resDecrypt.errors?.length ?? 0 > 0) { throw new Error(resDecrypt.errors!.join('|')); }\n\n if (!resDecrypt.decryptedData) { throw new Error(`(UNEXPECTED) resDecrypt has no errors but resDecrypt.decryptedData falsy? (E: 06e73992fb02e45e3c18db33f9a61b23)`); }\n\n // we're done\n return resDecrypt.decryptedData;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n // async unwrapEncryptedSyncSpace({\n // encryptedSpace,\n // fnPromptPassword,\n // dontPrompt,\n // space,\n // fnSpaceFactory,\n // }: {\n // encryptedSpace: IbGibSpaceAny,\n // fnPromptPassword: (title: string, msg: string) => Promise<string | null>,\n // dontPrompt?: boolean,\n // space?: IbGibSpaceAny,\n // fnSpaceFactory: (syncSpaceIbGib: SyncSpaceIbGib) => Promise<IbGibSpaceAny>,\n // }): Promise<IbGibSpaceAny> {\n // const lc = `${this.lc}[${this.unwrapEncryptedSyncSpace.name}]`;\n // try {\n // // validation\n // if (!space) { throw new Error(`space required (E: d4d3eaa2d7b9143cf1173b8ae6344c23)`); }\n // if (!encryptedSpace.rel8ns?.ciphertext) { throw new Error(`encryptedSpace is not a ciphertext (E: be5504a5e2b84f3eaa8fbd6e13aab659)`); }\n // if (encryptedSpace.rel8ns!.ciphertext!.length !== 1) { throw new Error(`only 1 ciphertext rel8n allowed... (E: e8ab2ec38ad844dfb229efc5b8981946)`); }\n\n // // get ciphertext ibgib\n // const ciphertextAddr = encryptedSpace.rel8ns!.ciphertext![0];\n // const resCiphertext = await this.get({ addr: ciphertextAddr, space });\n // if (!resCiphertext.success) { throw new Error(`get ciphertext failed (E: e58b3471c0334cd7bc626998106e6547)`); }\n // if ((resCiphertext.ibGibs || []).length !== 1) { throw new Error(`get ciphertext retrieved non-1 length (eesh) (E: a3a1f00e827b4f88a42b4a7433cf1065)`); }\n // const ciphertextIbGib = resCiphertext.ibGibs![0] as CiphertextIbGib_V1;\n\n // // get secrets associated with enciphered space\n // if (!encryptedSpace.rel8ns?.secret) { throw new Error(`!encryptionIbGib.rel8ns?.secret (E: 8bfed1541976433da9402d7d3a9138dd)`); }\n // const secretAddrs = encryptedSpace.rel8ns!.secret!;\n // const localUserSpace = await this.getLocalUserSpace({});\n // if (!localUserSpace) { throw new Error(`(UNEXPECTED) could not get localUserSpace? (E: 3c5687a15b3b58e3dcf1eca4f5fe5723) (E: c123b340177647968e10a6b119d84d2b)`); }\n // const argGetSecrets = await localUserSpace.argy({\n // argData: { ibGibAddrs: secretAddrs, cmd: 'get', }\n // });\n // const resSecrets = await localUserSpace.witness(argGetSecrets);\n // if (!resSecrets.data?.success || (resSecrets.ibGibs || []).length === 0) {\n // throw new Error(`couldn't get secret ibgibs (E: cb17687f842f4296a9ecf89d9a568e46)`);\n // }\n // const secretIbGibs = resSecrets.ibGibs.concat() as IbGib_V1<SecretData_V1>[];\n\n // // get plaintext now that we have the ciphertext ibgib and secret ibgib(s)\n // const plaintextString = await this.getPlaintextString({\n // ciphertextIbGib,\n // fnPromptPassword,\n // dontPrompt,\n // secretIbGibs,\n // space,\n // });\n\n // const syncSpaceData = JSON.parse(plaintextString) as OuterSpaceData;\n // if (syncSpaceData.type !== 'sync') { throw new Error(`syncSpaceData.type !== 'sync'...this is the only one implemented right now (E: 509b2373d6f8445ebe5bd6f27f62af93)`); }\n // if (syncSpaceData.subtype !== 'aws-dynamodb') { throw new Error(`syncSpaceData.subtype !== 'aws-dynamodb'...only one right now dude (E: b5caaf3b4c60438eb2cee58ce8e1d3f6)`); }\n\n // // this is the original aws only implementation. I've just added (untested)\n // // a quick factory function where the consumer would do the following code.\n // const unwrappedSpace = await fnSpaceFactory(syncSpaceData);\n // return unwrappedSpace;\n // // so we have a syncspace data (only aws-dynamodb space right now).\n // // load this data into a space class with behavior (not just the dto).\n // // const awsSpace = new AWSDynamoSpace_V1(syncSpaceData, null);\n // // awsSpace.gib = await getGib({ ibGib: awsSpace, hasTjp: false });\n // // if (logalot) { console.log(`awsSpace.gib: ${awsSpace.gib}`); }\n // // return awsSpace;\n\n // } catch (error) {\n // console.error(`${lc} ${error.message}`);\n // throw error;\n // }\n // }\n\n /**\n * Caching user password secret in memory only.\n *\n * Just to prevent plaintext passwords from just sitting in memory,\n * this is a slight layer of indirection for caching\n *\n * @returns user password\n */\n protected async getCachedSecretPassword({\n cacheKey,\n }: {\n cacheKey: string,\n }): Promise<string | undefined> {\n const lc = `${this.lc}[${this.getCachedSecretPassword.name}]`;\n try {\n if (!cacheKey) { throw new Error(`secretAddr required`); }\n let entry = this.passwordCache[cacheKey];\n if (!entry) {\n if (logalot) { console.log(`${lc} secretAddr not cached: ${cacheKey}`); }\n return undefined;\n }\n\n // settings must match, but I'm feeling lazy on DRYing\n\n if (logalot) { console.log(`${lc} starting decrypt...`); }\n let resDecrypt = await decrypt({\n encryptedData: entry.encryptedPassword,\n secret: entry.tempMetaPassword,\n initialRecursions: 10000,\n recursionsPerHash: 5,\n salt: entry.salt,\n saltStrategy: 'appendPerHash',\n hashAlgorithm: 'SHA-512',\n });\n if (logalot) { console.log(`${lc} decrypt complete.`); }\n\n if (!resDecrypt.decryptedData) { throw new Error(`resDecrypt.decryptedData falsy`); }\n\n return resDecrypt.decryptedData;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n }\n\n protected async setCachedSecretPassword({\n cacheKey,\n secretPassword,\n force,\n }: {\n cacheKey: string,\n secretPassword: string,\n force?: boolean,\n }): Promise<void> {\n const lc = `${this.lc}[${this.getCachedSecretPassword.name}]`;\n try {\n if (!cacheKey) { throw new Error(`secretAddr required`); }\n\n if (this.passwordCache[cacheKey]) {\n if (force) {\n if (logalot) { console.log(`already cached, but force is true: ${cacheKey}`); }\n delete this.passwordCache[cacheKey];\n } else {\n if (logalot) { console.log(`already cached: ${cacheKey}`); }\n return undefined;\n }\n }\n\n const tempMetaPassword = await getUUID(256);\n const salt = await getUUID();\n // settings must match, but I'm feeling lazy on DRYing\n let resEncrypt = await encrypt({\n dataToEncrypt: secretPassword,\n secret: tempMetaPassword,\n initialRecursions: 10000,\n recursionsPerHash: 5,\n salt: salt,\n saltStrategy: 'appendPerHash',\n hashAlgorithm: 'SHA-512',\n });\n if (!resEncrypt.encryptedData) { throw new Error(`resEncrypt.encryptedData falsy`); }\n const encryptedPassword = resEncrypt.encryptedData!;\n\n let entry: TempCacheEntry =\n { tempMetaPassword, salt, encryptedPassword, };\n\n this.passwordCache[cacheKey] = entry;\n if (logalot) { console.log(`${lc} entry added for ${cacheKey}.`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return undefined;\n }\n }\n\n /**\n * If we don't have outerspaces/cloud endpoints, we'll do that here.\n *\n * @returns true if creation was successfully created, else false.\n */\n protected async _createOuterspaceAndRequiredIbGibs({\n space,\n fnPromptSecret,\n fnPromptEncryption,\n fnPromptOuterSpace,\n }: {\n space: IbGibSpaceAny,\n fnPromptSecret: (space: IbGibSpaceAny) => Promise<SecretIbGib_V1 | undefined>,\n fnPromptEncryption: (space: IbGibSpaceAny) => Promise<EncryptionIbGib_V1 | undefined>,\n fnPromptOuterSpace: (space: IbGibSpaceAny) => Promise<IbGibSpaceAny | undefined>,\n }): Promise<boolean> {\n const lc = `${this.lc}[${this._createOuterspaceAndRequiredIbGibs.name}]`;\n try {\n const createdSecret = await this._createSecret({ space, fnPromptSecret });\n if (logalot) { console.log(`${lc} createdSecret: ${createdSecret} (I: 9fc011d8ecb1e10c86c86025be4d5c22)`); }\n if (!createdSecret) { return false; } // <<<< returns early\n\n const createdEncryption = await this._createEncryption({ space, fnPromptEncryption });\n if (logalot) { console.log(`${lc} createdEncryption: ${createdEncryption} (I: 6796bbeb7338471e965cf1806d0dea9c)`); }\n if (!createdEncryption) { return false; } // <<<< returns early\n\n const createdOuterspace = await this._createOuterspace({ space, fnPromptOuterSpace });\n if (logalot) { console.log(`${lc} createdOuterspace: ${createdOuterspace} (I: 6796bbeb7338471e965cf1806d0dea9c)`); }\n return createdOuterspace;\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false;\n }\n }\n\n protected async _createSecret({\n space,\n fnPromptSecret,\n }: {\n space: IbGibSpaceAny,\n fnPromptSecret: (space: IbGibSpaceAny) => Promise<SecretIbGib_V1 | undefined>,\n }): Promise<boolean> {\n const lc = `${this.lc}[${this._createSecret.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const alert = this.getFnAlert!();\n\n let secretIbGibs: IbGib_V1[] = await this.getSpecialRel8dIbGibs({\n type: \"secrets\",\n rel8nName: SECRET_REL8N_NAME,\n space,\n });\n if (secretIbGibs.length === 0) {\n await alert({\n title: 'first create some stuff...',\n msg: \"First we'll need to do a couple things, like create a secret password, an encryption setting, and a cloud endpoint.\",\n });\n }\n while (secretIbGibs.length === 0) {\n let secretIbGib = await fnPromptSecret(space);\n if (secretIbGib === undefined) {\n await alert({ title: 'cancelled', msg: 'Cancelled.' });\n return false;\n }\n await this.registerNewIbGib({ ibGib: secretIbGib, });\n await this.rel8ToSpecialIbGib({\n type: \"secrets\",\n rel8nName: SECRET_REL8N_NAME,\n ibGibsToRel8: [secretIbGib],\n space,\n });\n secretIbGibs = await this.getSpecialRel8dIbGibs({\n type: \"secrets\",\n rel8nName: SECRET_REL8N_NAME,\n space,\n });\n }\n return true;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async _createEncryption({\n space,\n fnPromptEncryption,\n }: {\n space: IbGibSpaceAny,\n fnPromptEncryption: (space: IbGibSpaceAny) => Promise<EncryptionIbGib_V1 | undefined>,\n }): Promise<boolean> {\n const lc = `${this.lc}[${this._createEncryption.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const alert = this.getFnAlert!();\n\n let encryptionIbGibs: IbGib_V1[] = await this.getSpecialRel8dIbGibs({\n type: \"encryptions\",\n rel8nName: ENCRYPTION_REL8N_NAME,\n space,\n });\n if (encryptionIbGibs.length === 0) {\n await alert({\n title: 'next create an encryption...',\n msg: \"Now we need to create an encryption setting. If you don't know what this is, just fill in the requirements and leave the others as defaults.\",\n });\n }\n while (encryptionIbGibs.length === 0) {\n let encryptionIbGib = await fnPromptEncryption(space);\n if (encryptionIbGib === undefined) {\n await this.getFnAlert!()({ title: 'cancelled', msg: 'Cancelled.' });\n return false;\n }\n await this.registerNewIbGib({ ibGib: encryptionIbGib, space });\n await this.rel8ToSpecialIbGib({\n type: \"encryptions\",\n rel8nName: ENCRYPTION_REL8N_NAME,\n ibGibsToRel8: [encryptionIbGib],\n space,\n });\n encryptionIbGibs = await this.getSpecialRel8dIbGibs({\n type: \"encryptions\",\n rel8nName: ENCRYPTION_REL8N_NAME,\n space,\n });\n }\n return true;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async _createOuterspace({\n space,\n fnPromptOuterSpace,\n }: {\n space: IbGibSpaceAny,\n fnPromptOuterSpace: (space: IbGibSpaceAny) => Promise<IbGibSpaceAny | undefined>,\n }\n ): Promise<boolean> {\n const lc = `${this.lc}[${this._createOuterspace.name}]`;\n try {\n const alert = this.getFnAlert!();\n let outerspaceIbGibs: IbGib_V1[] = await this.getSpecialRel8dIbGibs({\n type: \"outerspaces\",\n rel8nName: SYNC_SPACE_REL8N_NAME,\n space,\n });\n if (outerspaceIbGibs.length === 0) {\n await alert({\n title: 'Now to outerspace...',\n msg: `Great! Now we can create an outerspace ibgib, which is like a connection from this local space to other spaces (like the cloud).`,\n });\n }\n while (outerspaceIbGibs.length === 0) {\n let outerspaceIbGib = await fnPromptOuterSpace(space);\n if (outerspaceIbGib === undefined) { break; }\n await this.registerNewIbGib({ ibGib: outerspaceIbGib, space });\n await this.rel8ToSpecialIbGib({\n type: \"outerspaces\",\n rel8nName: SYNC_SPACE_REL8N_NAME,\n ibGibsToRel8: [outerspaceIbGib],\n space,\n });\n await alert({\n title: 'Good job',\n msg: `Great! Now we can use this space to synchronize & import ibgibs.`,\n });\n outerspaceIbGibs = await this.getSpecialRel8dIbGibs({\n type: \"outerspaces\",\n rel8nName: SYNC_SPACE_REL8N_NAME,\n space,\n });\n }\n if (outerspaceIbGibs.length > 0) {\n return true;\n } else {\n await alert({ title: 'cancelled', msg: 'Cancelled.' });\n return false;\n }\n } catch (error) {\n console.log(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n // async getSyncSpaces({\n // createIfNone,\n // dontPrompt,\n // space,\n // outerspaceIds,\n // // fnSpaceFactory,\n // fnPromptSecret,\n // fnPromptEncryption,\n // fnPromptOuterSpace,\n // }: {\n // // unwrapEncrypted: boolean,\n // createIfNone: boolean,\n // /**\n // * If true, don't prompt the user if we don't have it already cached.\n // *\n // * We don't want the user to hit the page and then always have to type in\n // * the password, just because my password code sucks atow.\n // */\n // dontPrompt?: boolean,\n // space?: IbGibSpaceAny,\n // /**\n // * @see {@link syncIbGibs} arg of the same name\n // */\n // outerspaceIds?: SpaceId[],\n // // fnSpaceFactory: (unencryptedSpaceData: any) => Promise<IbGibSpaceAny>,\n // fnPromptSecret: (space: IbGibSpaceAny) => Promise<SecretIbGib_V1 | undefined>,\n // fnPromptEncryption: (space: IbGibSpaceAny) => Promise<EncryptionIbGib_V1 | undefined>,\n // fnPromptOuterSpace: (space: IbGibSpaceAny) => Promise<IbGibSpaceAny | undefined>,\n // }): Promise<SyncSpaceIbGib[]> {\n // const lc = `${this.lc}[${this.getSyncSpaces.name}]`;\n // try {\n // space = space ?? await this.getLocalUserSpace({});\n // if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: bf09346708ba4d6e9a1389bd1b66d500)`); }\n\n // // get existing\n // let resSyncSpaces: SyncSpaceIbGib[] =\n // await this.getSpecialRel8dIbGibs<SyncSpaceIbGib>({\n // type: \"outerspaces\",\n // rel8nName: SYNC_SPACE_REL8N_NAME,\n // space,\n // });\n\n // // filter if applicable\n // const hasOuterspaceIds = (outerspaceIds?.length ?? 0) > 0;\n // if (hasOuterspaceIds) {\n // resSyncSpaces = resSyncSpaces.filter(x => outerspaceIds!.includes(x.data!.uuid!));\n // }\n\n // // create if applicable\n // if (resSyncSpaces.length === 0) {\n // if (createIfNone) {\n // if (hasOuterspaceIds) { throw new Error(`(UNEXPECTED) both createIfNone true and outerspaceIds (filter) also true? you cannot have both of these set, it's one of the other. (E: 9caaa121dee3e41e6e29916614cd4e24)`); }\n // const createdReqs = await this._createOuterspaceAndRequiredIbGibs({\n // space,\n // fnPromptSecret,\n // fnPromptEncryption,\n // fnPromptOuterSpace,\n // });\n // if (createdReqs) {\n // resSyncSpaces = await this.getSpecialRel8dIbGibs<SyncSpaceIbGib>({\n // type: \"outerspaces\",\n // rel8nName: SYNC_SPACE_REL8N_NAME,\n // space,\n // });\n // }\n // } else {\n // throw new Error(`No sync spaces found. First create a sync outerspace (like a cloud sync space) in order to synchronize with it (E: 8f395f226ac7b558b9317befefbcb724)`);\n // }\n // }\n\n // // unwrap if requested\n // // let resSpaces: SyncSpaceIbGib[] = [];\n // // if (unwrapEncrypted) {\n // // for (let i = 0; i < syncSpaceIbGibs.length; i++) {\n // // let syncSpace = syncSpaceIbGibs[i];\n\n // // if (syncSpace.rel8ns) {\n // // if (syncSpace.rel8ns.ciphertext) {\n // // syncSpace = await this.unwrapEncryptedSyncSpace({\n // // encryptedSpace: syncSpace,\n // // fnPromptPassword: this.getFnPromptPassword!(),\n // // dontPrompt,\n // // space,\n // // fnSpaceFactory,\n // // });\n // // }\n\n // // resSpaces.push(syncSpace);\n // // } else {\n // // }\n\n // // }\n // // } else {\n // // still (probably) encrypted\n // // resSpaces = syncSpaceIbGibs;\n // // }\n\n // // return resSpaces;\n // return resSyncSpaces;\n // } catch (error) {\n // console.error(`${lc} ${error.message}`);\n // return [];\n // }\n // }\n\n // async createRobbotIbGib({\n // robbotData,\n // space,\n // }: {\n // robbotData: RobbotData_V1,\n // space?: IbGibSpaceAny,\n // }): Promise<{ newRobbotIbGib: RobbotIbGib_V1, newRobbotsAddr: string }> {\n // const lc = `${this.lc}[${this.createRobbotIbGib.name}]`;\n // try {\n // space = space ?? await this.getLocalUserSpace({});\n // if (!space) { throw new Error(`space falsy and localUserSpace not initialized (E: 33ea7f4633484afa984225d037478ac4)`); }\n\n // return createRobbotIbGib({\n // robbotData,\n // space,\n // zeroSpace: this.zeroSpace,\n // fnBroadcast: (x) => this.fnBroadcast(x),\n // fnUpdateBootstrap: (x) => this.fnUpdateBootstrap(x),\n // });\n // } catch (error) {\n // console.error(`${lc} ${error.message}`);\n // throw error;\n // }\n // }\n\n async getAppRobbotIbGibs({\n createIfNone,\n fnPromptRobbot,\n space,\n }: {\n createIfNone: boolean,\n fnPromptRobbot: (space: IbGibSpaceAny, ibGib: RobbotIbGib_V1 | null) => Promise<RobbotPromptResult | undefined>;\n space?: IbGibSpaceAny,\n }): Promise<RobbotIbGib_V1[]> {\n const lc = `${this.lc}[${this.getAppRobbotIbGibs.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: bf09346708ba4d6e9a1389bd1b66d500)`); }\n\n // get existing. Note that these are not the robbot witnesses, but only\n // the robbot ibgib (dtos). They do not have a `witness` function on them\n // at this point.\n let appRobbots_MaybeOutOfDate: RobbotIbGib_V1[] =\n await this.getSpecialRel8dIbGibs<RobbotIbGib_V1>({\n type: \"robbots\",\n rel8nName: ROBBOT_REL8N_NAME,\n space,\n });\n\n let appRobbots: RobbotIbGib_V1[] = [];\n for (let i = 0; i < appRobbots_MaybeOutOfDate.length; i++) {\n let robbotIbGib = appRobbots_MaybeOutOfDate[i];\n let robbotAddr = getIbGibAddr({ ibGib: robbotIbGib });\n const latestAddr = await this.getLatestAddr({ ibGib: robbotIbGib, space });\n if (latestAddr && latestAddr !== robbotAddr) {\n // robbot has a newer ibgib in its timeline\n let resGet = await this.get({ addr: latestAddr, space });\n if (!resGet || !resGet?.success || (resGet?.ibGibs ?? []).length === 0) {\n throw new Error(`could not get newer robbot ibgib (E: 15fa346c8ac17edb96e4b0870104c122)`);\n }\n robbotIbGib = resGet.ibGibs![0] as RobbotIbGib_V1;\n robbotAddr = getIbGibAddr({ ibGib: robbotIbGib });\n }\n\n const errors = await validateCommonRobbotIbGib({ robbotIbGib });\n if ((errors ?? []).length === 0) {\n // only add if robbot doesn't have validation errors\n appRobbots.push(robbotIbGib);\n } else {\n console.error(`${lc} robbot ibGib (${robbotAddr}) has validation errors: ${errors}`)\n }\n }\n\n // create if applicable\n\n if (appRobbots.length === 0 && createIfNone) {\n console.error(`${lc} creating new robbot but should be not casting this on next line in src code. (E: 3252c5917e11421dbc1c26b280b8aeef)`);\n let robbot = await createNewRobbot({ ibgibs: this as any, space, fnPromptRobbot });\n if (robbot) {\n appRobbots = await this.getSpecialRel8dIbGibs<RobbotIbGib_V1>({\n type: \"robbots\",\n rel8nName: ROBBOT_REL8N_NAME,\n space,\n });\n }\n }\n\n return appRobbots;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return [];\n }\n }\n\n async getAppAppIbGibs({\n createIfNone,\n fnPromptApp,\n space,\n }: {\n createIfNone: boolean,\n /**\n * factory function for creating/editing an app ibgib.\n *\n * @param space space within which we're working\n * @param ibGib set if editing app, null if creating\n * @returns TransformResult<IbGibAppAny> for app ibgib created/edited\n */\n fnPromptApp: (space: IbGibSpaceAny, ibGib: AppIbGib_V1 | null) => Promise<AppPromptResult | undefined>,\n space?: IbGibSpaceAny,\n }): Promise<AppIbGib_V1[]> {\n const lc = `${this.lc}[${this.getAppAppIbGibs.name}]`;\n try {\n space = space ?? await this.getLocalUserSpace({});\n if (!space) { throw new Error(`space falsy and localUserSpace not initialized (?) (E: a5aec4d94f764c6a964179bbb743b577)`); }\n\n // get existing. Note that these are not the app witnesses, but only\n // the app ibgib (dtos). They do not have a `witness` function on them\n // at this point.\n let appApps_MaybeOutOfDate: AppIbGib_V1[] =\n await this.getSpecialRel8dIbGibs<AppIbGib_V1>({\n type: \"apps\",\n rel8nName: APP_REL8N_NAME,\n space,\n });\n\n let appApps: AppIbGib_V1[] = [];\n for (let i = 0; i < appApps_MaybeOutOfDate.length; i++) {\n const appIbGib = appApps_MaybeOutOfDate[i];\n const appAddr = getIbGibAddr({ ibGib: appIbGib });\n const latestAddr = await this.getLatestAddr({ ibGib: appIbGib });\n if (latestAddr && latestAddr !== appAddr) {\n // app has a newer ibgib in its timeline\n let resGet = await this.get({ addr: latestAddr, space });\n if (!resGet || !resGet?.success || (resGet?.ibGibs ?? []).length === 0) {\n throw new Error(`could not get newer app ibgib (E: de6a77634b1e4e16914ef110bb263d7c)`);\n }\n appApps.push(resGet.ibGibs![0] as AppIbGib_V1);\n } else {\n appApps.push(appIbGib);\n }\n }\n\n // create if applicable\n if (appApps.length === 0 && createIfNone) {\n console.error(`${lc} creating new app but should be not casting this on next line in src code. (E: 3252c5917e11421dbc1c26b280b8aeef)`);\n let app = await createNewApp({ ibgibs: this as any, space, fnPromptApp });\n if (app) {\n appApps = await this.getSpecialRel8dIbGibs<AppIbGib_V1>({\n type: \"apps\",\n rel8nName: APP_REL8N_NAME,\n space,\n });\n }\n }\n\n return appApps;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return [];\n }\n }\n\n // #region syncIbGibs related\n\n protected subSagaSyncTimeLog: SubscriptionWitness | undefined;\n\n async syncIbGibs({\n localSpace,\n dependencyGraphIbGibs,\n syncSpaceIbGibs,\n // watch,\n }: {\n /**\n * @see {@link MetaspaceService.syncIbGibs}\n */\n localSpace: IbGibSpaceAny,\n /**\n * @see {@link MetaspaceService.syncIbGibs}\n */\n dependencyGraphIbGibs?: IbGib_V1[],\n /**\n * @see {@link MetaspaceService.syncIbGibs}\n */\n syncSpaceIbGibs: IbGibSpaceAny[],\n // /**\n // * If true, will watch ibgibs in dependency graph that have timelines\n // * (tjps).\n // */\n // watch?: boolean,\n }): Promise<SyncSagaInfo[] | undefined> {\n const lc = `${this.lc}[${this.syncIbGibs.name}]`;\n // map of saga infos across all spaces\n // const sagaInfoMap: { [spaceGib: string]: SyncSagaInfo } = {};\n try {\n if (this.syncing) {\n console.warn(`already syncing. (E: dfa3ad58e97f4b18b4e4d7dc252208fb)`);\n return;\n }\n if (Object.values(this.sagaInfoMap).length > 0) { throw new Error(`this._syncing is false but sagaInfoMap not cleaned up(?). (E: bb69c808877c4931b5481585043c18e7)(UNEXPECTED)`); }\n\n this._syncing = true;\n\n // have to make sagaId and syncStatus$ early to enable timeLog calls\n const sagaId = (await getUUID()).slice(0, 24);\n const syncStatus$ = await newupSubject<SyncStatusIbGib>({ replay: true });\n const syncTimelogName = `sync_log ${sagaId}`;\n console.time(syncTimelogName);\n console.timeLog(syncTimelogName, 'start');\n this.subSagaSyncTimeLog = await syncStatus$.subscribe(fnObs<SyncStatusIbGib>({\n next: async (status) => {\n // debugger; // metaspacebase syncIbGibs next\n if (logalot) { console.log(`${lc}[obs.next] next called (I: 9af8d3267b0ff473fe5f8024f0dbed23)`); }\n if (status.data?.statusCode === StatusCode.completed) {\n console.timeLog(syncTimelogName, 'StatusCode.complete');\n }\n },\n error: async (_: any) => {\n // debugger; // metaspacebase syncIbGibs error\n if (logalot) { console.log(`${lc}[obs.error] error called (I: 976b08ab82d64299b17927eac16b1693)`); }\n console.timeEnd(syncTimelogName)\n if (!this.subSagaSyncTimeLog) {\n console.error(`${lc}[obs.error] (unexpected) this.subSagaSyncTimeLog falsy (E: e1e82df8a1d94e7fbe55f638f3b4a53e)`)\n }\n await this.subSagaSyncTimeLog!.unsubscribe();\n },\n complete: async () => {\n // debugger; // metaspacebase syncIbGibs complete\n if (logalot) { console.log(`${lc}[obs.complete] complete called (I: 72307340e2b34b22b0787e3a3c906c06)`); }\n console.timeEnd(syncTimelogName)\n if (!this.subSagaSyncTimeLog) {\n console.error(`${lc}[obs.complete] (unexpected) this.subSagaSyncTimeLog falsy (E: 89429f426206444d8d6431492e585213)`)\n }\n await this.subSagaSyncTimeLog?.unsubscribe();\n }\n }));\n\n // #region validate\n if (logalot) { console.log(`${lc} starting...`); }\n if (!dependencyGraphIbGibs || dependencyGraphIbGibs.length === 0) { throw new Error(`dependencyGraphIbGibs required. (E: 404c36475fb84fc285a23a67c0b8fcb2)`); }\n if (!syncSpaceIbGibs || syncSpaceIbGibs.length === 0) { throw new Error(`syncSpaceIbGibs required (E: c5a022454b9ce34856e141e61e337d24)`); }\n // #endregion\n\n const localUserSpace = localSpace ?? await this.getLocalUserSpace({});\n if (!localUserSpace?.data) { throw new Error(`localUserSpace?.data falsy (E: e7ff57e4d529cde903619078ee9b6e23)`); }\n if (!localUserSpace.gib) { throw new Error(`localUserSpace.gib falsy (E: 884d86d20e7a4468b3c8b2c3ab7dba7e)`); }\n\n // #region get sync spaces and build participant infos\n if (logalot) { console.log(`${lc} get sync spaces (returns if none)`); }\n const participants: ParticipantInfo[] = [\n // local user space is the src\n { id: localUserSpace.data.uuid, gib: localUserSpace.gib, s_d: 'src', },\n\n // each sync space is a destination\n ...syncSpaceIbGibs.map(s => {\n if (!s.data) { throw new Error(`syncSpaceIbGib.data required. (E: 3c192771e84445a4b6476d5193b07e9d)`); }\n if (!s.data.uuid) { throw new Error(`syncSpaceIbGib.data.uuid required. (E: d27e9998227840f99d45a3ed245f3196)`); }\n if (!s.gib) { throw new Error(`syncSpaceIbGib.gib required. (E: db73aceb2f8445d8964ae49b59957072)`); }\n return { id: s.data.uuid, gib: s.gib, s_d: 'dest', } satisfies ParticipantInfo;\n }),\n ];\n // #endregion\n\n // _NOW_ we can finally put/merge into sync spaces.\n // this returns to us the most recent versions which we can update\n // our local timelines if we so choose (which we will).\n // NOTE: we won't worry about what if different sync spaces have different\n // versions atm. We're just going to do this assuming sync spaces\n // are nice and coordinated (which they aren't).\n\n if (logalot) { console.log(`${lc} syncing to spaces in parallel...`); }\n const multiSpaceOpId = await getUUID();\n const allSagaInfos: SyncSagaInfo[] = [];\n const startSyncPromises: Promise<void>[] = syncSpaceIbGibs.map(async syncSpace => {\n // create the info that will track progress over entire sync saga\n const sagaInfo =\n await this._createNewSyncSagaInfo({\n multiSpaceOpId,\n allIbGibsToSync: dependencyGraphIbGibs,\n syncSpace,\n participants,\n sagaId,\n syncStatus$,\n });\n this.sagaInfoMap[sagaInfo.sagaId] = sagaInfo;\n allSagaInfos.push(sagaInfo);\n try {\n // _startSync creates a status observable that can keep us up to date\n // on the status updates throughout the sync saga. We can handle\n // updating our own local space based on those status updates.\n\n // taking out watch for now\n // await this._startSync({ syncSagaInfo: sagaInfo, watch: false, syncTimelogName });\n await this._startSync({ syncSagaInfo: sagaInfo, syncTimelogName });\n } catch (error) {\n // if this throws, then that is unexpected. The above result should\n // always be returned, and if it's errored then it should indicate as\n // such.\n console.error(`${lc} (UNEXPECTED) ${error.message}`);\n throw error;\n }\n });\n\n // await just the initial starting of each space's sync operation. when\n // this promise is awaited, the sync operation is not done, only the\n // starting of all sync sagas across all spaces.\n console.timeLog(syncTimelogName, 'awaiting all startSyncPromises starting...');\n await Promise.all(startSyncPromises);\n console.timeLog(syncTimelogName, 'awaiting all startSyncPromises complete.');\n\n // at this point, all spaces have prepared and are going. the sync saga\n // info attached to each arg/result ibgib has the observable syncStatus$\n // that will produce the status updates which can be interpreted &\n // responded to.\n await this._handleSagaUpdates();\n return allSagaInfos;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n await this._finalizeAllSyncSagas_NoThrow({ error });\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async _finalizeSyncSaga({\n sagaInfo,\n error,\n }: {\n sagaInfo: SyncSagaInfo,\n error?: any,\n }): Promise<void> {\n const lc = `${this.lc}[${this._finalizeSyncSaga.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if (sagaInfo.complete) { return; }\n if (!sagaInfo.syncStatus$) { throw new Error(`(UNEXPECTED) this.syncStatus$ falsy? (E: 1fc3817823752f66a6a190b8107fe523)`); }\n // if (!sagaInfo.syncStatus$.closed) {\n if (!sagaInfo.syncStatus$.isCompleteOrErrored) {\n if (error) {\n const emsg =\n typeof (error) === 'string' ? error : error.message ??\n `${lc} something went wrong (E: d7db873d9e8b4f14b5b490cadd9730f4)`;\n console.error(emsg);\n if (!sagaInfo.syncStatus$.error) { throw new Error(`(UNEXPECTED) sagaInfo.syncStatus$.error is falsy? (E: 8522f275dbbf0885db75aead27d72923)`); }\n await sagaInfo.syncStatus$.error!(emsg);\n }\n // we don't call complete() from within a next() (i don't think)\n // if (!sagaInfo.syncStatus$.complete) { throw new Error(`(UNEXPECTED) sagaInfo.syncStatus$.complete is falsy? (E: 836f42d8f7084ff9afd73696134d41e6)`); }\n // if (!sagaInfo.syncStatus$.isCompleteOrErrored) {\n // await sagaInfo.syncStatus$.complete();\n // }\n }\n // I think $.complete() closes subscriptions, but to be double sure...\n let toUnsubscribe: SubscriptionWitness[] = [];\n const subscriptions = (sagaInfo.syncStatusSubscriptions ?? []);\n for (let i = 0; i < subscriptions.length; i++) {\n const sub = subscriptions[i];\n let unsubscribed = await sub.unsubscribed();\n if (!unsubscribed) {\n await sub.unsubscribe();\n }\n }\n\n if (logalot) { console.log(`${lc} setting sagaInfo.complete to true (I: 85c34469cdac404782c2024ad6b6fbd1)`); }\n sagaInfo.complete = true;\n this._updateSagaInfoMapAndIsSyncingFlag();\n\n if (logalot) { console.log(`${lc} complete.`); }\n } catch (err) {\n console.error(`${lc} ${err.message}`);\n if (logalot) { console.log(`${lc} setting sagaInfo.complete to true (I: 23de6ef45eaf47a1918038dce3da7d78)`); }\n sagaInfo.complete = true;\n throw err;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async _finalizeAllSyncSagas_NoThrow({\n error,\n }: {\n error?: any,\n }): Promise<void> {\n const lc = `${this.lc}[${this._finalizeAllSyncSagas_NoThrow.name}]`;\n try {\n const syncSagaInfos_NotComplete =\n Object.values(this.sagaInfoMap).filter(x => !x.complete);\n for (let i = 0; i < syncSagaInfos_NotComplete.length; i++) {\n const sagaInfo = syncSagaInfos_NotComplete[i];\n await this._finalizeSyncSaga({ sagaInfo, error });\n }\n } catch (error) {\n console.error(`${lc}(UNEXPECTED) ${error.message}`);\n // caller expects does NOT rethrow!\n } finally {\n this._updateSagaInfoMapAndIsSyncingFlag();\n }\n }\n\n protected _updateSagaInfoMapAndIsSyncingFlag(): void {\n const lc = `${this.lc}[${this._updateSagaInfoMapAndIsSyncingFlag.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const sagaInfoKeys = Object.keys(this.sagaInfoMap || {});\n\n if (sagaInfoKeys.length === 0) {\n this.sagaInfoMap = {};\n if (this._syncing) { this._syncing = false; }\n return; /* <<<< returns early */\n }\n\n const sagaInfos = Object.values(this.sagaInfoMap);\n if (sagaInfos.every(info => info.complete)) {\n if (logalot) { console.log(`${lc} all sagaInfos are complete. finalizing sync. (I: f6d94deb5509e6b2e5371b9bfc007422)`); }\n this.sagaInfoMap = {};\n this._syncing = false;\n if (logalot) { console.log(`${lc} this._syncing is now false.`); }\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async _createNewSyncSagaInfo({\n multiSpaceOpId,\n allIbGibsToSync,\n syncSpace,\n participants,\n sagaId,\n syncStatus$,\n }: {\n multiSpaceOpId: string,\n allIbGibsToSync: IbGib_V1[],\n syncSpace: IbGibSpaceAny,\n participants: ParticipantInfo[],\n /**\n * have to make this early to enable the console.time/Log calls.\n */\n sagaId: string,\n /**\n * have to make this early to enable the console.time/Log calls.\n */\n syncStatus$: SubjectWitness<SyncStatusIbGib>,\n }): Promise<SyncSagaInfo> {\n const lc = `${this.lc}[${this._createNewSyncSagaInfo.name}]`;\n try {\n if (!multiSpaceOpId) { throw new Error(`multiSpaceOpId required. (E: a7e228dbd63948d784a67ddbb342e4f7)`); }\n if (!syncSpace.data) { throw new Error(`syncSpace.data required. (E: 1c44334cf4545de147ef2dc675406a23)`); }\n\n // do the addrs outside of info initializer\n const syncAddrs_All = allIbGibsToSync.map(x => getIbGibAddr({ ibGib: x }));\n const syncAddrs_All_WithTjps = allIbGibsToSync\n .filter(x => hasTjp({ ibGib: x }))\n .map(x => getIbGibAddr({ ibGib: x }));\n const syncAddrs_All_AreTjps = allIbGibsToSync\n .filter(x => x.gib !== GIB && x.data?.isTjp === true)\n .map(x => getIbGibAddr({ ibGib: x }));\n const syncAddrs_All_WithoutTjps =\n syncAddrs_All.filter(addr => !syncAddrs_All_WithTjps.includes(addr));\n\n // do the info initializer\n const syncSagaInfo: SyncSagaInfo = {\n multiSpaceOpId,\n outerSpace: syncSpace,\n // spaceGib: syncSpace.gib,\n spaceId: syncSpace.data.uuid,\n sagaId,\n participants,\n witnessFnArgsAndResults$: await newupSubject<SyncSpaceOptionsIbGib | SyncSpaceResultIbGib>({ replay: true }),\n\n // syncStatus$: new ReplaySubject<SyncStatusIbGib>(),\n syncStatus$,\n syncStatusSubscriptions: [],\n\n syncIbGibs_All: allIbGibsToSync,\n syncAddrs_All,\n syncAddrs_All_AreTjps,\n syncAddrs_All_WithTjps,\n syncAddrs_All_WithoutTjps,\n syncAddrs_Skipped: [],\n syncAddrs_ToDo: [],\n syncAddrs_InProgress: [],\n syncAddrs_Failed: [],\n };\n\n const syncTimelogName = `sync_log ${syncSagaInfo.sagaId}`;\n // console.time(syncTimelogName);\n console.timeLog(syncTimelogName);\n // return it\n return syncSagaInfo;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * this {@link IbGibsService} acts as the local app space intermediary,\n * a broker between the local space and the sync space(s). So this\n * function's job is to coordinate sending the given ibgibs\n * to a single sync space and return the observable (subject)\n * corresponding to the multi-step sync process.\n *\n * The caller will be responsible for coordinating among sync\n * space results and handling updates to local space ibgib's,\n * such as rebasing/updating/etc.\n *\n * @returns\n */\n protected async _startSync({\n syncSagaInfo,\n // watch,\n syncTimelogName,\n }: {\n syncSagaInfo: SyncSagaInfo,\n // watch?: boolean,\n syncTimelogName: string,\n }): Promise<SyncSpaceResultIbGib> {\n const lc = `${this.lc}[${this._startSync.name}]`;\n try {\n const {\n multiSpaceOpId, participants, sagaId, outerSpace: syncSpace,\n syncIbGibs_All,\n syncAddrs_All, syncAddrs_All_WithTjps: syncAddrs_All_Tjps, syncAddrs_All_WithoutTjps: syncAddrs_All_NonTjps,\n } = syncSagaInfo;\n\n // first we want to get the ball rolling\n // we will get back an ibGib that we can use to track the progress of the\n // entire operation wrt this space.\n console.timeLog(syncTimelogName, `getLocalUserSpace starting...`);\n const localUserSpace = await this.getLocalUserSpace({});\n if (!localUserSpace) { throw new Error(`localUserSpace required (E: e01fc13ce7c5a802b50aa0f9b2c13a23)`); }\n if (!localUserSpace.data) { throw new Error(`localUserSpace.data required (E: e01fc13ce7c5a802b50aa0f9b2c13a23)`); }\n console.timeLog(syncTimelogName, `getLocalUserSpace complete.`);\n\n const argStartSync: SyncSpaceOptionsIbGib = await syncSpace.argy({\n argData: {\n // cmd: 'put', cmdModifiers: watch ? ['sync', 'watch'] : ['sync'],\n cmd: 'put', cmdModifiers: ['sync'],\n sagaId,\n participants,\n ibGibAddrs: syncAddrs_All,\n ibGibAddrs_All_Tjps: syncAddrs_All_Tjps,\n ibGibAddrs_All_NonTjps: syncAddrs_All_NonTjps,\n } as SyncSpaceOptionsData,\n ibGibs: syncIbGibs_All, // do we need to do this yet?\n ibMetadata: `sync src ${localUserSpace.data.name} srcId ${localUserSpace.data.uuid}`,\n });\n argStartSync.syncSagaInfo = syncSagaInfo;\n\n // atow we only have one cycle. in the future, I think we will be having the possibility\n // of multiple cycles, which is why I have this structured as an observable\n // and not hard-coding a single arg/result in the saga info.\n syncSagaInfo.witnessFnArgsAndResults$.next(argStartSync);\n console.timeLog(syncTimelogName, `syncSpace witness starting...`);\n const resStartSync: SyncSpaceResultIbGib = await syncSpace.witness(argStartSync);\n console.timeLog(syncTimelogName, `syncSpace witness complete.`);\n if (!resStartSync.data?.statusTjpAddr) { throw new Error(`resStartSync.data.statusTjpAddr is falsy. sagaId: ${sagaId} (E: 727b5cc1a0254497bc6e06e9c6760564)`); }\n syncSagaInfo.witnessFnArgsAndResults$.next(resStartSync);\n\n // in our return, we can check for updates since our last communication.\n // if (Object.keys(resStartSync.data.watchTjpUpdateMap ?? {}).length > 0) {\n // if (logalot) { console.log(`${lc} resStartSync.data.watchTjpUpdateMap: ${pretty(resStartSync.data.watchTjpUpdateMap)}`); }\n // console.timeLog(syncTimelogName, `handleWatchTjpUpdates starting...`);\n // await this.handleWatchTjpUpdates({\n // outerSpace: syncSpace,\n // updates: resStartSync.data.watchTjpUpdateMap,\n // localUserSpace,\n // });\n // console.timeLog(syncTimelogName, `handleWatchTjpUpdates complete.`);\n // }\n\n // most of our handling will be in subscription to syncStatus$ updates.\n return resStartSync;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Coming in to this function, we have results from one or more\n * sync spaces. Here are the combinations of expected outcomes:\n *\n * 1. All success, each returns the exact same new ib^gib address(es).\n * 2. All success, but different spaces return different ib^gib address(es).\n * 3. Some success, which returns exact same new ib^gib, some error.\n * 4. Some success, more than one ib^gib address(es), some error.\n * 5. All error.\n *\n * For the first naive implementation, we will always be optimistic,\n * assuming that errors will be resolved with enough attempts. This\n * is closely related to our initial optimistic strategy of\n * \"access is authorization\" + \"unordered dna equivalence\". These\n * strategies mean that we are simply, optimistically, and\n * naively applying incoming dna transforms to ibgib timelines.\n * So failure should only result from a failure at the communication\n * layer, assuming non-adversarial conditions.\n *\n * ## future\n *\n * The handling of this should absolutely be generalized to the\n * requirements for interspatial relationships. This is the language\n * that must be implemented to deal with this in a dynamic fashion.\n *\n * This does not equate to only \"ad hoc\" in the sense of untested/untried.\n * This means that we have an \"on-chain\", public linked requirement\n * for consensus as opposed to a hard-coded consensus as is defined\n * in this function.\n *\n * It is in this generalization that byzantine resolution can be\n * achieved through whichever mechanism is correct for the use case.\n */\n protected async _handleSagaUpdates(): Promise<void> {\n const lc = `${this.lc}[${this._handleSagaUpdates.name}]`;\n try {\n // at this point in execution, each space has returned the result ibgib\n // which has a syncStatus$ observable.\n\n const infos = Object.values(this.sagaInfoMap);\n for (let i = 0; i < infos.length; i++) {\n const sagaInfo = infos[i];\n\n let sub = await sagaInfo.syncStatus$\n .subscribe(fnObs({\n next: async (status: SyncStatusIbGib) => {\n // debugger; // metaspacebase handlesagaupdates next\n if (logalot) { console.log(`${lc}(sagaId: ${sagaInfo.sagaId}) subscribe next triggered. status: ${status?.data?.statusCode} (I: 41e1f61e5e1b422ead1d72a1c92c7d51)`); }\n await this._handleSyncStatusIbGib({ status, sagaInfo });\n },\n error: async (error: string) => {\n // debugger; // metaspacebase handlesagaupdates error\n const emsg = `${lc}(sagaId: ${sagaInfo.sagaId}) syncStatus$.error: ${error}`;\n console.error(emsg);\n // await this.getFnAlert!()({title: 'couldnt this.syncIbGibs...', msg: emsg});\n await this._finalizeSyncSaga({ sagaInfo, error: emsg });\n },\n complete: async () => {\n // debugger; // metaspacebase handlesagaupdates complete\n if (logalot) { console.log(`${lc}(sagaId: ${sagaInfo.sagaId}) syncStatus$.complete.`); }\n await sub.unsubscribe(); // differs from rxjs\n },\n }));\n // changing this to in the complete handler because i think\n // my rx design and rxjs differs. they had some sort of\n // reference counting/scope magic that would kill the\n // observable if no subscriptions or something. i don't\n // remember. anyway, i think I can just unsubscribe in\n // complete with mine.\n // if (sagaInfo.syncStatusSubscriptions) { sagaInfo.syncStatusSubscriptions.push(sub); }\n // if (!sagaInfo.syncStatusSubscriptions) { throw new Error(`sagaInfo.syncStatusSubscriptions array falsy? (E: f6d834beaa164c6ea1073d35b9fecd01)`) }\n // sagaInfo.syncStatusSubscriptions.push(sub);\n }\n\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n protected async _handleSyncStatusIbGib({\n status,\n sagaInfo,\n }: {\n status: SyncStatusIbGib,\n sagaInfo: SyncSagaInfo,\n }): Promise<void> {\n const lc = `${this.lc}[${this._handleSyncStatusIbGib.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n // #region validate\n if (!status) { throw new Error(`falsy status. (E: 8da370a9f3df48a98cc08f1cccf5f2dc)`); }\n if (!status.data) { throw new Error(`falsy status.data. (E: 996d458c5cde4622ba1ed54c7e188815)`); }\n if (!status.data.statusCode) { throw new Error(`falsy status.data.statusCode (E: 7f2bec6b9dd0484eb7ef97966e6dd027)`); }\n // #endregion validate\n\n const localSpaceId = getSrcLocalSpaceId({ participants: sagaInfo.participants });\n const localSpace = await this.getLocalUserSpace({ lock: false, localSpaceId });\n if (!localSpace) { throw new Error(`(UNEXPECTED) couldn't get the local space (id: ${localSpaceId}) in the middle of a saga? (E: b921a1530148ccdae688cb8a13715324)`); }\n const resStoreStatusLocally =\n await this.put({ ibGibs: status.statusIbGibGraph, space: localSpace });\n if (!resStoreStatusLocally.success) {\n // just log for now...the saving is supposed to the the log in the first place.\n console.error(`${lc}(UNEXPECTED) couldn't save status graph locally? sagaId: ${sagaInfo.sagaId} (E: b472101897824195b96b658c441dfb55)`);\n }\n const statusCode = status.data.statusCode;\n if (logalot) { console.log(`${lc} status update received. statusCode: ${statusCode}. sagaId: ${sagaInfo.sagaId}. spaceId: ${sagaInfo.spaceId}`); }\n\n switch (statusCode) {\n case StatusCode.started:\n // nothing to do on start? hmm...\n break;\n\n case StatusCode.inserted:\n // await this.handleSyncComplete_Inserted({sagaInfo, status});\n // nothing further to do? hmm...\n break;\n\n case StatusCode.updated:\n // await this.handleSyncComplete_Updated({sagaInfo, status});\n // nothing further to do? hmm...\n break;\n\n case StatusCode.merged_dna:\n await this._handleSyncStatus_Merged({ status, sagaInfo });\n break;\n\n case StatusCode.merged_state:\n await this._handleSyncStatus_Merged({ status, sagaInfo });\n break;\n\n case StatusCode.already_synced:\n // await this.handleSyncComplete_AlreadySynced({sagaInfo, status});\n // nothing further to do? hmm...\n break;\n\n case StatusCode.completed:\n await this._handleSyncStatus_Complete({ sagaInfo });\n break;\n\n case StatusCode.undefined:\n // atow undefined is used in primitive status parentage\n throw new Error(`statusCode is \"undefined\". Maybe published a primitive? sagaId: ${sagaInfo.sagaId} (E: c98376f35b194adf9bf12ff9259a2569)`);\n\n default:\n // ?\n throw new Error(`(UNEXPECTED) unknown status.data.statusCode (${status.data.statusCode}). sagaId: ${sagaInfo.sagaId} (E: e4872abfc1ae4c27905793ca0f937a9b)`);\n }\n if (logalot) { console.log(`${lc} complete.`); }\n } catch (error) {\n const emsg = `${lc} ${error.message}`;\n console.error(emsg);\n if (!sagaInfo.syncStatus$?.error) {\n throw new Error(`(UNEXPECTED) sagaInfo.syncStatus$.error falsy? (E: 36cc488835aeb12e1ae6b7a49d0d8523)`);\n }\n await sagaInfo.syncStatus$.error(emsg);\n }\n };\n\n protected async _handleSyncStatus_Merged({\n status,\n sagaInfo,\n }: {\n status: SyncStatusIbGib,\n sagaInfo: SyncSagaInfo,\n }): Promise<void> {\n const lc = `${this.lc}[${this._handleSyncStatus_Merged.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n // #region validate\n\n // not necessarily the case, if we only have changes on the store side, we apply no dna and create no side effects\n if ((status.createdIbGibs ?? []).length === 0 &&\n (status.storeOnlyIbGibs ?? []).length === 0\n ) { throw new Error('status.createdIbGibs and/or status.storeOnlyIbGibs required when merging. (E: d118bde47fb9434fa95d747f8e4f6b33)'); }\n\n if (Object.keys(status.ibGibsMergeMap ?? {}).length === 0) { throw new Error('status.ibGibsMergeMap required when merging. (E: 0f06238e5535408f8980e0f9f82cf564)'); }\n\n // #endregion validate\n\n if (logalot) { console.log(`${lc} validated.`); }\n\n const localSpaceId = getSrcLocalSpaceId({ participants: sagaInfo.participants });\n const localSpace = await this.getLocalUserSpace({ localSpaceId });\n if (!localSpace) { throw new Error(`(UNEXPECTED) couldn't get src participant with space id (${localSpaceId}) in the middle of a saga? (E: c75732b748f6a168254e38dc5548e824)`); }\n\n // first, we will store the newly created ibgibs in the local space. Then\n // we want to rebase our local timeline to point to the new one. I believe\n // we can do this simply by registering the latest created ibgib which\n // will record it as the local latest ibgib in the tjp timeline. It may be\n // best to somehow tag the rebased ibgib, which would enable us to\n // optionally see this later without modifying the ibgib timeline by a\n // mut8 or rel8 function directly on the now-vestigial/abandoned timeline.\n\n /**\n * groups the incoming `ibGibsToRegister` by tjp and registers each latest.\n *\n * @param ibGibsToRegister will call `registerNewIbGib` on the lastest in each timeline\n */\n const registerLatestInTimelines = async (ibGibsToRegister: IbGib_V1[]) => {\n const timelines =\n getTimelinesGroupedByTjp({ ibGibs: ibGibsToRegister });\n for (let i = 0; i < Object.keys(timelines).length; i++) {\n const tjpAddr = Object.keys(timelines)[i];\n const timeline = timelines[tjpAddr];\n const latestIbGibInTimeline = timeline[timeline.length - 1];\n // registerNewIbGib is idempotent if already registered as latest\n await this.registerNewIbGib({ ibGib: latestIbGibInTimeline, space: localSpace });\n }\n };\n\n // first, we will store the newly created ibgibs (if any) in the local space.\n // created ibgibs may not exist if only the sync space branch has changed.\n // meanwhile, we must collect all ibgib timelines (with tjps) to register\n if (status.createdIbGibs?.length ?? 0 > 0) {\n if (logalot) { console.log(`${lc} putting createdIbGibs (${status.createdIbGibs!.length}): ${status.createdIbGibs!.map(x => getIbGibAddr({ ibGib: x })).join('\\n')}.`); }\n const resPutCreated = await this.put({ ibGibs: status.createdIbGibs, space: localSpace });\n if (!resPutCreated.success) { throw new Error(`Couldn't save created ibGibs locally? (E: f8bc91259c5043d589cd2e7ad2220c1f)`); }\n if (status.storeOnlyIbGibs) {\n await registerLatestInTimelines(status.storeOnlyIbGibs)\n }\n } else {\n if (logalot) { console.log(`${lc} no createdIbGibs`); }\n }\n\n\n if (status.storeOnlyIbGibs?.length ?? 0 > 0) {\n if (logalot) { console.log(`${lc} putting into local space the storeOnlyIbGibs (${status.storeOnlyIbGibs!.length}): ${status.storeOnlyIbGibs!.map(x => getIbGibAddr({ ibGib: x })).join('\\n')}.`); }\n console.warn(`${lc} putting storeOnlyIbGibs (${status.storeOnlyIbGibs!.length}): ${status.storeOnlyIbGibs!.map(x => getIbGibAddr({ ibGib: x })).join('\\n')}.`);\n const resPutStoreOnly = await this.put({ ibGibs: status.storeOnlyIbGibs, space: localSpace });\n if (!resPutStoreOnly.success) { throw new Error(`Couldn't save storeonly ibGibs locally? (E: c5ab044718ab42bba27f5852149b7ddc)`); }\n await registerLatestInTimelines(status.storeOnlyIbGibs!)\n } else {\n if (logalot) { console.log(`${lc} no storeOnlyIbGibs`); }\n }\n\n // download any dependency ibgibs from the new latest ibgib that we don't have already.\n\n // register the new latest ibgib.\n // merge map goes from old latest addr -> latest ibGib that was the result of the merge.\n let newLatestIbGibs = Object.values(status.ibGibsMergeMap ?? {});\n for (let i = 0; i < newLatestIbGibs.length; i++) {\n const latestIbGib = newLatestIbGibs[i];\n if (logalot) { console.log(`${lc} registering latestIbGib in localUserSpace: ${getIbGibAddr({ ibGib: latestIbGib })}`); }\n await this.registerNewIbGib({ ibGib: latestIbGib, space: localSpace });\n }\n\n if (logalot) { console.log(`${lc} complete.`); }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n protected async _handleSyncStatus_Complete({\n sagaInfo,\n }: {\n sagaInfo: SyncSagaInfo,\n }): Promise<void> {\n const lc = `${this.lc}[${this._handleSyncStatus_Complete.name}]`;\n try {\n // cleanup just this saga, which corresponds to a single sync space.\n await this._finalizeSyncSaga({ sagaInfo });\n\n // if this is the last saga across all spaces, clean up the rest.\n const allSagaInfos = Object.values(this.sagaInfoMap);\n if (allSagaInfos.every(x => x.complete)) {\n await this._finalizeAllSyncSagas_NoThrow({});\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n await this._finalizeAllSyncSagas_NoThrow({ error });\n }\n }\n\n protected async _getLatestIbGibsWithTjps({\n ibGibs,\n warnIfMultipleLocalTimelines,\n }: {\n ibGibs: IbGib_V1[],\n /**\n * I've already written the code to check for this. But I think\n * this will be normal when put/merging.\n */\n warnIfMultipleLocalTimelines?: boolean,\n }): Promise<IbGib_V1[]> {\n const lc = `${this.lc}[${this._getLatestIbGibsWithTjps.name}]`;\n try {\n const result: IbGib_V1[] = [];\n const ibGibsWithTjp_Ungrouped = ibGibs.filter(x =>\n x.data?.isTjp || (x.rel8ns?.tjp?.length ?? 0) > 0 || x.gib?.includes(GIB_DELIMITER)\n );\n // group them by tjp\n const ibGibsWithTjp_GroupedByTjpGib =\n groupBy({ items: ibGibsWithTjp_Ungrouped, keyFn: x => getGibInfo({ gib: x.gib }).tjpGib ?? '' });\n const tjpGibs = Object.keys(ibGibsWithTjp_GroupedByTjpGib);\n for (let i = 0; i < tjpGibs.length; i++) {\n const group = ibGibsWithTjp_GroupedByTjpGib[tjpGibs[i]];\n if (warnIfMultipleLocalTimelines) {\n // quick check to warn if we have multiple n's for a tjpGib (multi-timeline)\n let nCounts: { [key: number]: number } = {};\n for (const ibGibFrame of group) {\n let n = ibGibFrame.data?.isTjp ? -1 : (ibGibFrame.data?.n ?? -2);\n if (n === -2) { throw new Error(`ibGibFrame.data.n is undefined. We're only working with those with n right now!`); }\n nCounts[n] = (nCounts[n] ?? 0) + 1;\n }\n if (Object.values(nCounts).some(count => count > 1)) {\n console.warn(`${lc} we have multiple local timelines.`)\n }\n }\n\n // sort by n (ascending) and then grab the latest one\n const latestIbGibInGroup =\n group.sort((a, b) => (a.data?.n ?? -1) > (b.data?.n ?? -1) ? 1 : -1)[group.length - 1];\n result.push(latestIbGibInGroup);\n }\n\n // we're done\n return result;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n // #endregion syncIbGibs related\n\n // #region autosync\n\n async enableAutosync({\n tjpIbGibs,\n }: {\n tjpIbGibs: IbGib_V1[],\n }): Promise<void> {\n const lc = `${this.lc}[${this.enableAutosync.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if ((tjpIbGibs ?? []).length === 0) { throw new Error(`tjps required. (E: 3e3bb6ef1a3d483795440e0efcef8e04)`); }\n\n // validate tjps\n if (tjpIbGibs.some(tjp => !tjp.data?.isTjp)) {\n const wonkyTjpAddrs =\n tjpIbGibs\n .filter(tjp => !tjp.data?.isTjp)\n .map(x => getIbGibAddr({ ibGib: x }));\n console.warn(`${lc} unrelating tjp whose data.isTjp is false. tjpAddrs: ${wonkyTjpAddrs.join('|')} (W: 03b3d7a94e6d4ccaace3df4657a82322)`);\n }\n\n // we'll use addrs to compare to cache and autosync special ibgib\n let tjpAddrs = tjpIbGibs.map(tjp => getIbGibAddr({ ibGib: tjp }));\n\n // if we're already autosyncing all tjps, warn and return early check\n // locally since this is very fast/cheap\n let notAlreadySyncingTjpAddrs =\n tjpAddrs.filter(tjpAddr => !this._alwaysAutosyncTjpAddrsCache.has(tjpAddr));\n if (notAlreadySyncingTjpAddrs.length === 0) {\n console.warn(`${lc} all tjpAddrs already auto syncing. tjpAddrs: ${tjpAddrs.join('\\n')} (W: 7fbe51c8187840efa1b259417053bd22)`);\n return; /* <<<< returns early */\n }\n\n // ...and double check in autosyncs itself, more expensive though\n const autosyncsIbGib = await this.getSpecialIbGib({ type: \"autosyncs\" });\n if (!autosyncsIbGib?.rel8ns) { throw new Error(`autosyncsIbGib?.rel8ns falsy (E: 963313139e919c09aade8b8c412d7b23)`); }\n const alreadySyncing = autosyncsIbGib.rel8ns[AUTOSYNC_ALWAYS_REL8N_NAME] ?? [];\n notAlreadySyncingTjpAddrs = tjpAddrs.filter(tjpAddr => !alreadySyncing.includes(tjpAddr));\n if (notAlreadySyncingTjpAddrs.length === 0) {\n console.error(`${lc} (UNEXPECTED) all tjpAddrs already auto syncing per special ibgib. Proceeding without throwing here, but this means that the cache is out of sync with the special ibgib also. tjpAddrs: ${tjpAddrs.join('\\n')} (E: 574e163118f043fa8c50cfd575e62122)`);\n return; /* <<<< returns early */\n }\n\n // map back from tjp addrs to the tjp ibgibs\n const notAlreadySyncingTjps = notAlreadySyncingTjpAddrs.map(tjpAddr => {\n return tjpIbGibs.filter(tjp => getIbGibAddr({ ibGib: tjp }) === tjpAddr)[0];\n });\n\n // execute rel8 transform and plumbing\n await this.rel8ToSpecialIbGib({\n type: 'autosyncs',\n ibGibsToRel8: notAlreadySyncingTjps,\n rel8nName: AUTOSYNC_ALWAYS_REL8N_NAME,\n });\n\n // add to cache and we're done\n notAlreadySyncingTjpAddrs.forEach(tjpAddr => {\n this._alwaysAutosyncTjpAddrsCache.add(tjpAddr);\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n async disableAutosync({\n tjpIbGibs,\n }: {\n tjpIbGibs: IbGib_V1[],\n }): Promise<void> {\n const lc = `${this.lc}[${this.disableAutosync.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n if ((tjpIbGibs ?? []).length === 0) { throw new Error(`tjps required. (E: 7b7e34e20b5848b882e14ff8b6c53622)`); }\n\n if (tjpIbGibs.some(tjp => !tjp.data?.isTjp)) {\n const wonkyTjpAddrs =\n tjpIbGibs\n .filter(tjp => !tjp.data?.isTjp)\n .map(x => getIbGibAddr({ ibGib: x }));\n console.warn(`${lc} unrelating tjp whose data.isTjp is false. tjpAddrs: ${wonkyTjpAddrs.join('|')} (W: 7babdf67dda54a2a9905c6c45ef36522)`);\n }\n let tjpAddrs = tjpIbGibs.map(tjp => getIbGibAddr({ ibGib: tjp }));\n\n // if we're already autosyncing this tjp, warn and return early\n // check locally...\n // ...and double check in autosyncs itself.\n const autosyncsIbGib = await this.getSpecialIbGib({ type: \"autosyncs\" });\n if (!autosyncsIbGib?.rel8ns) { throw new Error(`(UNEXPECTED) invalid autosyncIbGibs. rel8ns falsy. (E: 5f6211c8a41896003db8bfc40230af22)`); }\n const alreadySyncing = autosyncsIbGib.rel8ns[AUTOSYNC_ALWAYS_REL8N_NAME] ?? [];\n const tjpAddrsToRemove: TjpIbGibAddr[] = [];\n tjpAddrs.forEach(tjpAddr => {\n if (alreadySyncing.includes(tjpAddr)) {\n if (logalot) { console.log(`${lc} disabling autosync for ${tjpAddr} (I: 63087804e6c436143971e5039b5e5e22)`); }\n tjpAddrsToRemove.push(tjpAddr);\n } else {\n if (logalot) { console.log(`${lc} already NOT auto syncing ${tjpAddr} (I: 88e00fea009964cd2bab4cc580aa2922)`); }\n }\n });\n if (tjpAddrsToRemove.length === 0) {\n console.warn(`${lc} tried to disable autosync for tjpAddrs but none were valid. returning early. (W: f9bdda90d906471aa56804d76b6e9522)`);\n return; /* <<<< returns early */\n }\n\n const uniqueTjpAddrsToRemove = Array.from(new Set(tjpAddrsToRemove));\n const tjpsToRemove = uniqueTjpAddrsToRemove.map(tjpAddr => {\n return tjpIbGibs.filter(tjp => getIbGibAddr({ ibGib: tjp }) === tjpAddr)[0];\n });\n\n\n // execute rel8 transform and plumbing\n await this.rel8ToSpecialIbGib({\n type: 'autosyncs',\n ibGibsToUnRel8: tjpsToRemove,\n rel8nName: AUTOSYNC_ALWAYS_REL8N_NAME,\n });\n\n // remove from cache and we're done\n uniqueTjpAddrsToRemove.forEach(tjpAddr => {\n this._alwaysAutosyncTjpAddrsCache.delete(tjpAddr);\n });\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async loadAutoSyncs(): Promise<void> {\n const lc = `${this.lc}[${this.loadAutoSyncs.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const autosyncsIbGib = await this.getSpecialIbGib({ type: \"autosyncs\" });\n if (!autosyncsIbGib) {\n console.warn(`${lc} autosyncsIbGib (\"autosyncs\") special ibgib not found not found. maybe fine, no idea. (W: 30ad2df15b38999106883358722fd425)`);\n return; /* <<<< returns early */\n }\n\n // if (!autosyncsIbGib?.rel8ns) { throw new Error(`autosyncsIbGib?.rel8ns falsy (E: 3fdcdf40f33c41ed9b7a01a079a8fd71)`); }\n\n if (autosyncsIbGib.rel8ns) {\n this._alwaysAutosyncTjpAddrsCache =\n new Set(autosyncsIbGib.rel8ns[AUTOSYNC_ALWAYS_REL8N_NAME]);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * checks to see if autosync is enabled for a given `tjp`.\n *\n * NOTE: this only checks cache atm.\n *\n * @returns true if autosync is enabled for the given tjp, else false\n */\n autosyncIsEnabled({\n tjp,\n }: {\n tjp: IbGib_V1,\n }): boolean {\n const lc = `${this.lc}[${this.autosyncIsEnabled.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n return this._alwaysAutosyncTjpAddrsCache.has(getIbGibAddr({ ibGib: tjp }));\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // #endregion autosync\n\n}\n", "/**\n * @module node-metaspace driven by a node+fs storage substrate\n *\n * a metaspace is a space of spaces. it adds/removes spaces and does\n * inter-spatial composition related things. it's similar to what people think\n * of in terms of a node in a p2p network.\n */\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGibSpaceAny } from '@ibgib/core-gib/dist/witness/space/space-base-v1.mjs';\nimport { IbGibCacheService } from '@ibgib/core-gib/dist/common/cache/cache-types.mjs';\nimport { MetaspaceBase } from '@ibgib/core-gib/dist/witness/space/metaspace/metaspace-base.mjs';\nimport { MetaspaceFactory } from '@ibgib/core-gib/dist/witness/space/metaspace/metaspace-types.mjs';\n\nimport { GLOBAL_LOG_A_LOT, GLOBAL_TIMER_NAME } from '../server-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n *\n */\nexport class Metaspace_Nodeindexedspace extends MetaspaceBase {\n\n // we won't get an object back, only a DTO ibGib essentially\n protected lc: string = `[${Metaspace_Nodeindexedspace.name}]`;\n\n get zeroSpace(): IbGibSpaceAny {\n const lc = `[${this.lc}][get zeroSpace]`;\n if (this.metaspaceFactory.fnZeroSpaceFactory) {\n return this.metaspaceFactory.fnZeroSpaceFactory();\n } else {\n throw new Error(`${lc} (UNEXPECTED) this.metaspaceFactory.fnZeroSpaceFactory falsy. not initialized? (E: 9e6c6954dacd868b18c9f34a71e63523)`);\n }\n }\n\n constructor(\n // public modalController: ModalController,\n // public alertController: AlertController,\n protected cacheSvc: IbGibCacheService | undefined,\n // private latestCacheSvc: IonicStorageLatestIbgibCacheService,\n ) {\n super(cacheSvc);\n const lc = `${this.lc}[ctor]`;\n if (logalot) {\n console.log(`${lc}${GLOBAL_TIMER_NAME}`);\n console.timeLog(GLOBAL_TIMER_NAME);\n console.log(`${lc} created. (I: 5690dc2ebf774df3a442bd463dee7455)`);\n }\n\n }\n\n protected async initializeMetaspaceFactory({ metaspaceFactory }: {\n metaspaceFactory: MetaspaceFactory,\n }): Promise<void> {\n const lc = `[${this.initializeMetaspaceFactory.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5a29670439ac47634dcdfe25225c8223)`); }\n if (!metaspaceFactory) { throw new Error(`(UNEXPECTED) metaspaceFactory falsy? space-gib server initialization should have guaranteed this to be truthy (E: f305356c2978cf0ee8062fd818940826)`); }\n if (!metaspaceFactory.fnDefaultLocalSpaceFactory) { throw new Error(`(UNEXPECTED) !metaspaceFactory.fnDefaultLocalSpaceFactory? space-gib server initialization should have guaranteed this to be truthy (E: 884281e5251bd65528eb7b3f48737826)`); }\n if (!metaspaceFactory.fnDtoToSpace) { throw new Error(`(UNEXPECTED) !metaspaceFactory.fnDtoToSpace? space-gib server initialization should have guaranteed this to be truthy (E: 885b7828606f36f9183bb9e687e25826)`); }\n if (!metaspaceFactory.fnZeroSpaceFactory) { throw new Error(`(UNEXPECTED) !metaspaceFactory.fnZeroSpaceFactory? space-gib server initialization should have guaranteed this to be truthy (E: 336cf6655758bad4aaeea8ce08d8c826)`); }\n\n await super.initializeMetaspaceFactory({ metaspaceFactory });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n // async initializeZeroSpace(): Promise<void> {\n // const lc = `[${this.initializeZeroSpace.name}]`;\n // try {\n // if (logalot) { console.log(`${lc} starting... (I: a3364e9601c70c8163e67868e5d67723)`); }\n\n // } catch (error) {\n // console.error(`${lc} ${extractErrorMsg(error)}`);\n // throw error;\n // } finally {\n // if (logalot) { console.log(`${lc} complete.`); }\n // }\n // }\n\n}\n", "/**\n * @module serve-gib/handler\n *\n * Base class and utilities for serve-gib handlers.\n */\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbAndGib } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../constants.mjs';\nimport { DomainInfo, ParamsWithDomain, RequestContext, ResponseResult, ServeGibHandler } from '../types.mjs';\nimport { ServeGibHttpMethod } from '../types.mjs';\nimport { bootstrapDomainMetaspace, getDomainRootPath } from '../../bootstrap-helper.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Abstract base class for serve-gib handlers.\n * Provides a \"pit of success\" plumbing for routing, error handling, and parameter parsing.\n *\n * @template TParams Type for the parsed query parameters.\n * @template TQueryParams Type for the parsed query parameters.\n */\nexport abstract class ServeGibHandlerBase<TParams = any, TQueryParams = any>\n implements ServeGibHandler<TParams, TQueryParams> {\n protected lc: string = `[${ServeGibHandlerBase.name}]`;\n\n /** The HTTP method this handler supports, or 'ALL' for catch-all. */\n protected abstract method: ServeGibHttpMethod;\n\n /** Regex for quick route matching via the default `canHandleRoute`. */\n protected abstract regex: RegExp;\n\n /**\n * The main entry point processing incoming requests.\n * Implements standard plumbing for matching, error handling, and param parsing.\n */\n async handleRoute(reqCtx: RequestContext<TParams, TQueryParams>): Promise<ResponseResult | undefined> {\n const lc = `${this.lc}[${this.handleRoute.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ad1a523a7bbd222db2e6ffab54f59c26)`); }\n\n // First check if we can handle it\n if (!this.canHandleRoute(reqCtx)) {\n if (logalot) { console.log(`${lc} cannot handle route. returning undefined. (I: 359bd4a9d44acb2408e3ad9570cfa526)`); }\n return undefined; /* <<<< returns early */\n }\n\n // prepare handling params, e.g., keystone/domain addr(s), ibgib\n // addr(s), not sure what else\n reqCtx.params = await this.parseParams(reqCtx);\n\n // prepare queryParams\n reqCtx.queryParams = await this.parseQueryParams(reqCtx);\n\n // hook to initialize contextual things like metaspace\n await this.initConcreteContext(reqCtx);\n\n // Delegate to implementation\n return await this.handleRouteImpl(reqCtx);\n\n } catch (error) {\n const emsg = `${lc} Error handling route: ${extractErrorMsg(error)}`;\n console.error(emsg);\n // Standard fallback error. Individual handlers can override with more specific catches in handleRouteImpl.\n return this.error(500, 'Internal Server Error', {\n errorMsg: emsg,\n method: this.method,\n regex: this.regex?.source,\n rawUrl: reqCtx?.rawUrl,\n });\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n /**\n * Concrete implementation of the handler logic.\n *\n * This is where the \"meat\" of the code goes, as there is some\n * pre-processing in the parent wrapper.\n */\n protected abstract handleRouteImpl(reqCtx: RequestContext<TParams, TQueryParams>): Promise<ResponseResult | undefined>;\n\n /**\n * Extracts per-handler/route params from a request context.\n *\n * @see {@link RequestContext.params}\n */\n parseParams(reqCtx: RequestContext<TParams, TQueryParams>): Promise<TParams | undefined> {\n const lc = `${this.lc}[${this.parseParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c08d98768f449317b8e4b56925d3b826)`); }\n return this.parseParamsImpl(reqCtx);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n /**\n * Concrete implementation for extracting params from a path.\n *\n * @see {@link RequestContext.params}\n */\n protected async parseParamsImpl(reqCtx: RequestContext<TParams, TQueryParams>): Promise<TParams | undefined> {\n const lc = `${this.lc}[${this.parseParamsImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 849e491b436860d6788b76c898b0a826)`); }\n\n if (logalot) { console.log(`${lc} default implementation in base class is a no-op (I: 88d128a11e1c66030839dc582486e826)`); }\n\n return undefined;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Hook to initialize concrete context, e.g., initializing a metaspace for the\n * specific domain. The base implementation is a no-op.\n */\n protected async initConcreteContext(reqCtx: RequestContext<TParams, TQueryParams>): Promise<void> {\n const lc = `${this.lc}[${this.initConcreteContext.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (logalot) { console.log(`${lc} default implementation in base class is a no-op`); }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Determines if this handler should attempt to handle the given request.\n *\n * Default implementation checks {@link method} and {@link regex} matching\n * against the pathname. Override for more advanced logic for edge cases.\n */\n protected canHandleRoute(reqCtx: RequestContext<TParams, TQueryParams>): boolean {\n const lc = `${this.lc}[${this.canHandleRoute.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: d790f637074feee63c4bfcb158f47826)`); }\n\n const isMethodMatch = this.method === 'ALL' || reqCtx.method === this.method;\n const isRegexMatch = this.regex.test(reqCtx.pathname);\n return isMethodMatch && isRegexMatch;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Parses query parameters from the URL.\n * Defaults to a basic key-value mapping of the URL search params.\n */\n protected async parseQueryParams(reqCtx: RequestContext<TParams, TQueryParams>): Promise<TQueryParams | undefined> {\n const lc = `${this.lc}[${this.parseQueryParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b5d985a4a58b8f3edff9f5ab500e5c26)`); }\n\n const queryParams: any = {};\n reqCtx.url.searchParams.forEach((value, key) => {\n queryParams[key] = value;\n });\n\n if (Object.keys(queryParams).length > 0) {\n // query params exist, validate and return if valid, throw if not\n const validationErrors = await this.validateQueryParams({ queryParams });\n if (validationErrors.length === 0) {\n return queryParams as TQueryParams;\n } else {\n throw new Error(`invalid query params. validationErrors: ${validationErrors.join(', ')} (E: 9355f8a9643803f52f2241f1c7f39826)`);\n }\n } else {\n // no query params given\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * base class implementation is a no-op. override this in descendant class\n * who expect the possibility of query params\n * @returns array of validation errors, empty if valid\n */\n protected async validateQueryParams({ queryParams }: { queryParams: any }): Promise<string[]> {\n const lc = `${this.lc}[${this.validateQueryParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 33b448e223c8682bd8b8b055cab86f26)`); }\n\n if (logalot) { console.log(`${lc} base class implementation is a no-op. returning empty array (i.e., valid) (I: 393e8db53d5a9e6ca8eb69ae25810826)`); }\n\n return [];\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Standard JSON success response.\n */\n protected ok(body: any, status: number = 200): ResponseResult {\n return { status, body, isJson: true };\n }\n\n /**\n * Standard JSON error response.\n */\n protected error(status: number, message: string, details?: any): ResponseResult {\n return { status, body: { error: message, details }, isJson: true };\n }\n\n /**\n * 404 Not Found response.\n */\n protected notFound(message: string = 'Not found'): ResponseResult {\n return this.error(404, message);\n }\n}\n\n/**\n * Base class for handlers that have to first initialize a metaspace in order to\n * process the incoming request.\n *\n * ## notes\n *\n * Some handlers, like those who do error handling or serving static files, do\n * not need to initialize a metaspace or do any get/put of any ibgibs. So those\n * don't need to descend from this class.\n *\n * But if the handler is one that has to put/get an ibgib, then a metaspace will\n * need to be init. Those handlers should descend from this class.\n */\nexport abstract class ServeGibHandlerWithMetaspaceBase<TParams extends ParamsWithDomain = ParamsWithDomain, TQueryParams = any>\n extends ServeGibHandlerBase<TParams, TQueryParams> {\n protected override lc: string = `[${ServeGibHandlerWithMetaspaceBase.name}]`;\n\n protected override async initConcreteContext(reqCtx: RequestContext<TParams, TQueryParams>): Promise<void> {\n const lc = `${this.lc}[${this.initConcreteContext.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n await this.initAndPopulateDomainContext(reqCtx);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected override parseParamsImpl(reqCtx: RequestContext<TParams, TQueryParams>): Promise<TParams | undefined> {\n const lc = `${this.lc}[${this.parseParamsImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f3ae6e662fe8d28db8c230e80a700826)`); }\n\n throw new Error(`(UNEXPECTED) not implemented. this function must be implemented in handlers that initialize metaspace. in that concrete handler class, you must parse out the raw path and build up the params object. That params object must at least include domain info, because that drives the multitenancy. (E: bd6a584b8f988f9ed81c77eedd36b826)`);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected override validateQueryParams({ queryParams }: { queryParams: any; }): Promise<string[]> {\n const lc = `${this.lc}[${this.validateQueryParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 14bb4659f9587d18786105c8e4966826)`); }\n\n throw new Error(`(UNEXPECTED) not implemented. this function must be implemented in handlers that initialize metaspace. in that concrete handler class, you must provide a function that validates query params expectations, even if you expect no query params. (E: 804c98a724ddf59998199ec87a9ee126)`);\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * helper that should extract the \"domain\" (driven by the correctly scoped\n * keystone) and set related props on the context.\n */\n protected async initAndPopulateDomainContext(reqCtx: RequestContext<TParams, TQueryParams>): Promise<void> {\n const lc = `${this.lc}[${this.initAndPopulateDomainContext.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!reqCtx.params) { throw new Error(`invalid RequestContext. params is falsy but we expected params.domainInfo at the minimum. (E: 433c15116e2e821768847d23f7853a26)`); }\n if (!reqCtx.params.domainInfo) { throw new Error(`invalid RequestContext. reqCtx.params is truthy but params.domainInfo is falsy. at this point, we should have parsed domain info from reqCtx.params (E: ae40882910aa6f45a810e268fd126f26)`); }\n\n const { domainInfo } = reqCtx.params as TParams\n const { addr: domainAddr, } = domainInfo;\n if (!domainAddr) {\n throw new Error(`(UNEXPECTED) domainAddr falsy? reqCtx.params does not contain domainIb and domainGib for a handler extending ServeGibHandlerWithMetaspaceBase. If extending this metaspace base, we are expected to have a domain addr with ib and gib. (E: 06bae6908ba8f200e8c50b28ed8df626)`);\n }\n\n // since we have access to reqCtx.dataDir, not sure if we need rootPath in DomainInfo?\n reqCtx.metaspace = await bootstrapDomainMetaspace(domainAddr, reqCtx.dataDir);\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Helper to build the domain info from a {@link domainAddr}.\n *\n * ## usage\n *\n * Use this helper function once your concrete handler has parsed the\n * domainAddr from the request url.\n *\n * For example, say the incoming path is /api/ibgib/:domainAddr/:ibgibAddr (GET)\n * Then the concrete handler for this path would pull out domainAddr, call\n * this function to build the domain info, and then put that domain info on\n * the `reqCtx`.\n */\n protected getDomainInfo({\n domainAddr,\n // dataDir,\n }: {\n /**\n * addr extracted from incoming url by concrete handler\n */\n domainAddr: IbGibAddr,\n // /**\n // * root dir of multitenancy on server. get from reqCtx.dataDir\n // */\n // dataDir: string,\n }): DomainInfo {\n const lc = `${this.lc}[${this.getDomainInfo.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 2d8bc8f40fd8ae3c98b84f6aaf6e0f26)`); }\n\n if (!domainAddr) { throw new Error(`(UNEXPECTED) domainAddr falsy? (E: 7009f98fead9712cb5d4c8985162c826)`); }\n\n const domainGibInfo = getGibInfo({ ibGibAddr: domainAddr });\n const { tjpGib, punctiliarHash } = domainGibInfo;\n const { ib: domainIb, gib: domainGib } = getIbAndGib({ ibGibAddr: domainAddr });\n const finalDomainGib = tjpGib || punctiliarHash;\n if (!finalDomainGib) { throw new Error(`(UNEXPECTED) finalDomainGib falsy? we have a domainAddr (${domainAddr}) so we should have a domain gib. (E: de1e18078678f3b4887ebfae3c893626)`); }\n\n const domainInfo: DomainInfo = {\n addr: domainAddr,\n gib: domainGib,\n ib: domainIb,\n gibInfo: domainGibInfo,\n // rootPath: getDomainRootPath(finalDomainGib, dataDir),\n }\n\n return domainInfo;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "/** Maximum allowed path length to prevent DoS. */\nexport const MAX_PATH_LENGTH = 2048;\n\n/**\n * Blacklisted patterns for any incoming path.\n * We iterate through these for a quick security check.\n */\nexport const FORBIDDEN_PATTERNS = [\n /\\.\\./, // No directory traversal\n /\\/\\//, // No redundant slashes\n /\\0/, // No null bytes\n /(^|\\/)\\./, // No hidden/dot-files (e.g. .env, .git)\n];\n\n/**\n * Regex for valid API paths.\n *\n * IMPORTANT: See IMPLEMENTATION.md for overall path schema documentation.\n *\n * Paths are URL encoded. The `ib` and `gib` portions of addresses are captured explicitly\n * by splitting on `%5E` or `^`.\n */\nexport const API_PATH_REGEXES = {\n /**\n * /api/health\n */\n HEALTH: /^\\/api\\/health\\/?$/,\n\n /**\n * /api/ibgib/graph/:domainAddr/:ibgibAddr\n */\n IBGIB_GRAPH: /^\\/api\\/ibgib\\/graph\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/?$/,\n\n /**\n * /api/ibgib/:domainAddr/:ibgibAddr\n */\n IBGIB_ADDR: /^\\/api\\/ibgib\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/?$/,\n\n /**\n * /api/keystone\n */\n KEYSTONE: /^\\/api\\/keystone\\/?$/,\n\n /**\n * /api/keystone/:domainAddr\n */\n KEYSTONE_ADDR: /^\\/api\\/keystone\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/?$/,\n\n /**\n * /api/ibgib\n */\n IBGIB_BASE: /^\\/api\\/ibgib\\/?$/,\n\n /**\n * /api/keystone/evolve/:domainAddr\n */\n KEYSTONE_EVOLVE: /^\\/api\\/keystone\\/evolve\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/?$/,\n\n /**\n * /api/keystone/genesis\n *\n * Accepts a single genesis-frame keystone ibgib and creates a new\n * domain-isolated metaspace for it. No `:domainAddr` in the URL because\n * the server derives the domain from the incoming keystone ibgib itself.\n *\n * Parallel to /api/keystone/evolve.\n */\n KEYSTONE_GENESIS: /^\\/api\\/keystone\\/genesis\\/?$/,\n\n /**\n * /api/debug/ws-echo\n *\n * Minimal WebSocket echo endpoint for validating WS plumbing (Traefik\n * passthrough, server upgrade handling, client connectivity) before\n * integrating real sync logic.\n *\n * ## intent\n *\n * NOT for production use. Remove or gate behind a flag once WS sync is\n * confirmed working end-to-end.\n */\n DEBUG_WS_ECHO: /^\\/api\\/debug\\/ws-echo\\/?$/,\n /**\n * /api/sync/ws/:domainAddr\n */\n SYNC_WS: /^\\/api\\/sync\\/ws\\/([^\\/]+?)(?:%5E|\\^)([^\\/]+)\\/?$/,\n};\n\nexport const VALID_STATIC_PATH_REGEX = /^\\/[a-zA-Z0-9\\-_\\.\\/]*$/;", "/**\n * @module serve-gib/handlers/api/health\n */\n\nimport { ServeGibHandlerBase } from '../handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../types.mjs';\nimport { API_PATH_REGEXES } from '../../../path-constants.mjs';\n\n/**\n * GET /api/health\n */\nexport class HealthHandler extends ServeGibHandlerBase {\n protected override method: ServeGibHttpMethod = 'ALL';\n protected override regex = API_PATH_REGEXES.HEALTH;\n\n protected async handleRouteImpl(reqCtx: RequestContext): Promise<ResponseResult | undefined> {\n if (reqCtx.method === 'GET') {\n return this.ok({ status: 'ok', timestamp: new Date().toISOString() });\n } else {\n throw new Error(`info.method !== 'GET' in ${HealthHandler.name} (E: bfff3c547b5827ca7845277804057f26)`);\n }\n }\n}\n", "import { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { validateIbGibAddr } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from './server-constants.mjs';\nimport { FORBIDDEN_PATTERNS, MAX_PATH_LENGTH, VALID_STATIC_PATH_REGEX } from './path-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * little helper function just to DRY out code.\n */\nexport function runtimeErrorValidationStrings(lc: string, error: any): string[] {\n const emsg = `${lc} ${extractErrorMsg(error)}`;\n console.error(emsg);\n return [`runtime error: ${emsg}`];\n}\n\n/**\n * Validates that a path is safe from common attacks and under max length.\n */\nexport function validateRawPath(rawPath: string): string[] {\n const lc = `[${validateRawPath.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 80bd6f63e6c83b8e943b90383e044826)`); }\n\n const errors: string[] = [];\n\n if (!rawPath || rawPath.length > MAX_PATH_LENGTH) {\n errors.push(`path too long. MAX_PATH_LENGTH: ${MAX_PATH_LENGTH}, incoming path length: ${rawPath.length}`);\n }\n\n for (const pattern of FORBIDDEN_PATTERNS) {\n if (pattern.test(rawPath)) {\n errors.push(`invalid path. contains forbidden pattern.source: ${pattern.source} (E: 56a228fb9473a086b83d0088b5af1826)`);\n }\n }\n\n return errors;\n } catch (error) {\n return runtimeErrorValidationStrings(lc, error);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * simple boolean wrapper for {@link validateRawPath}\n */\nexport function isSafePath(path: string): boolean {\n const errors = validateRawPath(path);\n return errors.length === 0;\n}\n\nexport function validateStaticPath(path: string): string[] {\n const lc = `[${validateStaticPath.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 4f9cf8ffd528c7dd88324529528eeb26)`); }\n\n const errors: string[] = [];\n\n if (!VALID_STATIC_PATH_REGEX.test(path)) {\n errors.push(`static path fails to match VALID_STATIC_PATH_REGEX of ${VALID_STATIC_PATH_REGEX} (E: dfdf38a0439d4d09186e6fa81ab66826) `);\n }\n\n return errors;\n } catch (error) {\n return runtimeErrorValidationStrings(lc, error);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Validates a static file path.\n */\nexport function isValidStaticPath(path: string): boolean {\n if (!isSafePath(path)) { return false; }\n const errors = validateStaticPath(path);\n return errors.length === 0;\n}\n\n/**\n * Decodes and validates a single ibGib address segment from a URL path.\n * Uses the library's internal validateIbGibAddr for deep checking.\n */\nexport function validateAddressSegment(encodedAddr: string): string[] {\n const lc = `[${validateAddressSegment.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1bb9ff7e1aefb77b670b2519658cc126)`); }\n if (!encodedAddr) {\n throw new Error(`(UNEXPECTED) falsy encodedAddr? We're expecting to have already guaranteed there are no double-slashes (i.e. no empty segments) (E: 7be7668e7b8c9fbbdf56f0fe19f92e26)`);\n }\n const addr = decodeURIComponent(encodedAddr);\n const errors = validateIbGibAddr({ addr });\n return errors ?? [];\n } catch (error) {\n return runtimeErrorValidationStrings(lc, error);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n", "import { IbGibAddr } from \"@ibgib/ts-gib/dist/types.mjs\";\r\n\r\nimport { DomainInfo } from \"../../../types.mjs\";\r\n\r\nexport interface IbGibParams {\r\n domainInfo: DomainInfo;\r\n ibGibIb: string;\r\n ibGibGib: string;\r\n ibGibAddr: IbGibAddr;\r\n}\r\n\r\n// #region IbGibGetQueryParams\r\nexport const DEFAULT_QUERY_PARAMS_GET_IBGIB = {\r\n /**\r\n * If true, will get the latest ibgib.\r\n */\r\n getLatest: false, // Default to false for regular ibgibs\r\n /**\r\n * If true, will get the ibgib's entire dependency graph\r\n */\r\n getGraph: false, // Default to false for regular ibgibs\r\n /**\r\n * If true, returns only the resolved address (addr) rather than the full\r\n * ibgib or graph body. Useful for a lightweight \"tip check\" before initiating\r\n * a full sync: client compares `latestAddr` with its locally known addr.\r\n *\r\n * ## notes\r\n *\r\n * Typically combined with `getLatest: true` to ask \"what is the server's\r\n * current tip for this timeline?\" without paying the cost of fetching the\r\n * full ibgib body or graph.\r\n *\r\n * When `getLatest: false` and `addrOnly: true`, returns the addr as-is\r\n * (i.e., confirms the given addr exists on the server).\r\n */\r\n addrOnly: false,\r\n};\r\n/**\r\n * @see {@link DEFAULT_QUERY_PARAMS_GET_IBGIB} key/values for jsdocs\r\n */\r\nexport type IbGibGetQueryParams = Partial<typeof DEFAULT_QUERY_PARAMS_GET_IBGIB>;\r\nexport type KNOWN_QUERY_PARAMS_IBGIB_GET = keyof IbGibGetQueryParams;\r\nexport const KNOWN_QUERY_PARAMS_IBGIB_GET = Object.keys(DEFAULT_QUERY_PARAMS_GET_IBGIB) as KNOWN_QUERY_PARAMS_IBGIB_GET[];\r\nexport function isKnownQueryParamsKey_IbGibGet(key: any): key is KNOWN_QUERY_PARAMS_IBGIB_GET {\r\n return !!key && typeof key === 'string' ?\r\n KNOWN_QUERY_PARAMS_IBGIB_GET.includes(key as any) :\r\n false;\r\n}\r\n// #endregion IbGibGetQueryParams\r\n", "/**\n * @module serve-gib/serve-gib-helpers\n * \n * General purpose helper functions for the serve-gib framework.\n */\n\n/**\n * Validates and coerces a boolean query parameter in place on the queryParams object.\n * \n * @param queryParams The parsed query parameters object\n * @param key The specific key to validate and coerce\n * @param errors Array to push error messages into if validation fails\n */\nexport function validateAndCoerceBooleanQueryParam(\n queryParams: any,\n key: string,\n errors: string[]\n): void {\n const rawVal = queryParams[key];\n if (typeof rawVal === 'string' &&\n (rawVal.toLowerCase() === 'true' || rawVal.toLowerCase() === 'false')\n ) {\n queryParams[key] = rawVal.toLowerCase() === 'true';\n } else if (typeof rawVal === 'boolean') {\n // do nothing, it's already a boolean\n } else if (rawVal !== undefined) {\n errors.push(`invalid value for \"${key}\". typeof should either be string or boolean. (E: c28ef87a2d4b4a6faef9a2c8db05b637)`);\n } else {\n // It's undefined, which means it wasn't provided in the URL.\n // We do not error here because default parameters apply later or it may be optional.\n }\n}\n", "/**\n * @module serve-gib/handlers/api/ibgib\n */\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';\nimport { ServeGibHandlerWithMetaspaceBase } from '../../handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../types.mjs';\nimport { validateAddressSegment } from '../../../../path-helper.mjs';\nimport { API_PATH_REGEXES } from '../../../../path-constants.mjs';\nimport {\n DEFAULT_QUERY_PARAMS_GET_IBGIB, IbGibGetQueryParams, IbGibParams,\n isKnownQueryParamsKey_IbGibGet, KNOWN_QUERY_PARAMS_IBGIB_GET\n} from './ibgib-handler-types.mjs';\nimport { validateAndCoerceBooleanQueryParam } from '../../../serve-gib-helpers.mjs';\n\nexport interface IbGibGraphResponseBody {\n addr: string;\n count: number;\n graph: Record<string, IbGib_V1>;\n}\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * GET /api/ibgib/:domainAddr/:ibGibAddr\n */\nexport class IbGibHandler extends ServeGibHandlerWithMetaspaceBase<IbGibParams, IbGibGetQueryParams> {\n protected override lc: string = `[${IbGibHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'GET';\n protected override regex = API_PATH_REGEXES.IBGIB_ADDR;\n\n protected override async parseParamsImpl(reqCtx: RequestContext<IbGibParams, IbGibGetQueryParams>): Promise<IbGibParams | undefined> {\n const lc = `${this.lc}[${this.parseParamsImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const match = reqCtx.pathname.match(this.regex);\n if (!match) { throw new Error(`(UNEXPECTED) match falsy for regex? at this point, we have passed canHandleRoute, so this should parse correctly. (E: 8ce0810a3a88f420639bf8286df1d826)`); }\n const domainIb = decodeURIComponent(match[1]);\n const domainGib = decodeURIComponent(match[2]);\n const domainAddr = getIbGibAddr({ ib: domainIb, gib: domainGib });\n const ibGibIb = decodeURIComponent(match[3]);\n const ibGibGib = decodeURIComponent(match[4]);\n const ibGibAddr = getIbGibAddr({ ib: ibGibIb, gib: ibGibGib });\n return {\n ibGibIb, ibGibGib, ibGibAddr,\n domainInfo: this.getDomainInfo({ domainAddr }),\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected override async validateQueryParams({ queryParams }: { queryParams: any; }): Promise<string[]> {\n const lc = `${this.lc}[${this.validateQueryParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const errors: string[] = [];\n\n // strict checking\n const queryParamsKeys = Object.keys(queryParams);\n const invalidKeys: string[] = queryParamsKeys.filter(x => !isKnownQueryParamsKey_IbGibGet(x));\n if (invalidKeys.length > 0) {\n throw new Error(`invalid query params keys: ${invalidKeys.join(', ')}. valid query params keys: ${KNOWN_QUERY_PARAMS_IBGIB_GET.join(', ')} (E: b7e8a9f2c1d34e56b89a01d4f2e7c326)`);\n }\n\n // Enforce that EVERY key must have a validation function mapping\n type ValidationFn = () => Promise<void>;\n const ValidationFns: Record<KNOWN_QUERY_PARAMS_IBGIB_GET, ValidationFn> = {\n getLatest: async () => validateAndCoerceBooleanQueryParam(queryParams, 'getLatest', errors),\n getGraph: async () => validateAndCoerceBooleanQueryParam(queryParams, 'getGraph', errors),\n addrOnly: async () => validateAndCoerceBooleanQueryParam(queryParams, 'addrOnly', errors),\n };\n\n // execute all validation functions\n for (const fn of Object.values(ValidationFns)) {\n await fn();\n }\n\n return errors;\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async handleRouteImpl(reqCtx: RequestContext<IbGibParams, IbGibGetQueryParams>): Promise<ResponseResult | undefined> {\n const lc = `${this.lc}[${this.handleRouteImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 03d6a889b1f8af879c0f7158a3b3de26)`); }\n\n if (logalot) { console.log(`${lc} starting... (I: 03d6a889b1f8af879c0f7158a3b3de26)`); }\n if (!reqCtx.metaspace) { throw new Error(`(UNEXPECTED) metaspace falsy? we should have initialized it by now since this is a domain-dependent handler (E: 864661c668d2aa1918b7ee677a7d9c26)`); }\n\n const { ibGibIb, ibGibGib } = reqCtx.params as IbGibParams;\n if (!ibGibIb || !ibGibGib) { return undefined; }\n\n // Reconstruct addr from params\n const rawAddr = `${ibGibIb}^${ibGibGib}`;\n if (!validateAddressSegment(rawAddr)) return this.error(400, 'Invalid address format');\n const addr = rawAddr;\n\n const queryParams = {\n ...DEFAULT_QUERY_PARAMS_GET_IBGIB,\n ...(reqCtx.queryParams ?? {}),\n };\n\n const { getLatest, getGraph, addrOnly } = queryParams;\n\n const space = await reqCtx.metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(`(UNEXPECTED) couldn't get default local user space? (E: ec6161ea3a08892ad8bfd1b7b0d79826)`); }\n\n let addr_latest: string = addr;\n if (getLatest) {\n const latestAddr = await reqCtx.metaspace.getLatestAddr({ addr, space });\n if (latestAddr) { addr_latest = latestAddr; }\n }\n\n // Lightweight tip-check: return only the resolved address.\n // Client uses this to decide whether a full sync is necessary\n // without incurring the cost of fetching the full ibgib or graph.\n if (addrOnly && !getGraph) {\n return this.ok({ addr: addr_latest, clientAddr: addr });\n } /* <<<<< returns early */\n\n if (getGraph) {\n const resGraph = await reqCtx.metaspace.getDependencyGraph({\n ibGibAddr: addr_latest,\n space,\n live: getLatest,\n });\n const addrs = Object.keys(resGraph);\n if (addrs.length > 0) {\n if (addrOnly) {\n // Return only the address list for delta negotiation (smart diff):\n // client compares these against what it already has to determine\n // the minimal set it needs to fetch.\n return this.ok({ addr: addr_latest, clientAddr: addr, addrs });\n } else {\n const responseBody: IbGibGraphResponseBody = {\n addr: addr_latest,\n count: addrs.length,\n graph: resGraph\n };\n return this.ok(responseBody);\n }\n } else {\n return this.notFound(`Graph not found for ${addr_latest} (E: 89b259f13ae5e4f0d8287f6c0475a826)`);\n }\n } else {\n const resGet = await reqCtx.metaspace.get({ space, addr: addr_latest });\n if (resGet.success && resGet.ibGibs?.length === 1) {\n const ibGib = resGet.ibGibs[0];\n return this.ok(ibGib);\n } else {\n return this.notFound(`IbGib not found for ${addr_latest} (E: 017621e0a8086832ff06cfc884b8c426)`);\n }\n }\n } catch (error) {\n if (logalot) { console.error(extractErrorMsg(error)) }\n return this.error(500, extractErrorMsg(error));\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "/**\n * @module serve-gib/handlers/api/keystone\n */\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';\nimport { ServeGibHandlerBase } from '../../handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../types.mjs';\nimport { API_PATH_REGEXES } from '../../../../path-constants.mjs';\nimport { KeystoneParams } from './keystone-handler-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * POST /api/keystone\n */\nexport class KeystonePostHandler extends ServeGibHandlerBase<KeystoneParams, any> { // todo: keystone post query params if needed?\n protected override lc: string = `[${KeystonePostHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'POST';\n protected override regex = API_PATH_REGEXES.KEYSTONE;\n\n protected async handleRouteImpl(reqCtx: RequestContext<KeystoneParams, any>): Promise<ResponseResult | undefined> {\n const lc = `[${this.handleRouteImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 63bab8214834cb6e383e0fc364ee8826)`); }\n\n const { metaspace } = reqCtx;\n if (!metaspace) { throw new Error(`(UNEXPECTED) reqCtx.metaspace falsy? (E: 3d03027ea7f6f237980e511801255826)`); }\n\n const { ibGibs } = JSON.parse(reqCtx.body) as { ibGibs: any[] };\n if (!Array.isArray(ibGibs)) return this.error(400, 'ibGibs array required');\n\n // 1. Intrinsic Validation\n for (const ibGib of ibGibs) {\n const errors = await validateIbGibIntrinsically({ ibGib });\n if (errors) {\n return this.error(422, 'Intrinsic validation failed', { failedAddr: getIbGibAddr({ ibGib }), errors });\n }\n }\n\n // 2. Keystone-specific checks\n for (const ibGib of ibGibs) {\n if (ibGib.ib?.startsWith('keystone')) {\n if (!reqCtx.metaspace) { return this.error(500, 'Metaspace not initialized'); }\n // Registration handles genesis vs evolution internally via metastones\n await reqCtx.metaspace.registerNewIbGib({\n ibGib,\n });\n }\n }\n\n // 3. Persistence\n console.log(`[KeystoneHandler] Persisting ${ibGibs.length} ibGibs...`);\n await metaspace.put({ ibGibs })\n // await spaceSvc.putIbGibGraph(ibGibs);\n console.log(`[KeystoneHandler] Persistence successful.`);\n return { status: 201, body: { success: true }, isJson: true };\n\n } catch (error) {\n const emsg = `${lc} ${extractErrorMsg(error)}`;\n console.error(emsg);\n return this.error(500, emsg);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "import { HashAlgorithm } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { IbGibAddr } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\n\nimport { KEYSTONE_ATOM } from \"./keystone-constants.mjs\";\nimport type { KeystoneVerb } from \"./keystone-constants.mjs\";\n\n// #region KeystoneChallengeType\nexport const KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1 = 'hash-reveal-v1';\n/**\n * The discriminator for the mechanism.\n * 'hash-reveal-v1': Standard Hash chain (Sigma-like).\n */\nexport type KeystoneChallengeType =\n | typeof KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1\n // | 'decrypt-v1' // Future\n // | 'pow-v1'; // Future\n ;\nexport const KeystoneChallengeType = {\n hash_reveal_v1: KEYSTONE_CHALLENGE_TYPE_HASH_REVEAL_V1,\n} satisfies { [key: string]: KeystoneChallengeType };\nexport const KEYSTONE_CHALLENGE_TYPE_VALID_VALUES = Object.values(KeystoneChallengeType);\nexport function isValidKeystoneChallengeType(x: any): x is KeystoneChallengeType {\n return typeof x === 'string' && KEYSTONE_CHALLENGE_TYPE_VALID_VALUES.includes(x as any);\n}\n// #endregion KeystoneChallengeType\n\n// ===========================================================================\n// CONFIGURATION\n// ===========================================================================\n\n// #region KeystoneReplenishStrategy\n/**\n * @see {@link KeystoneReplenishStrategy.topUp}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_TOP_UP = 'top-up';\n/**\n * @see {@link KeystoneReplenishStrategy.replaceAll}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL = 'replace-all';\n/**\n * @see {@link KeystoneReplenishStrategy.consume}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_CONSUME = 'consume';\n/**\n * @see {@link KeystoneReplenishStrategy.deleteAll}\n */\nexport const KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL = 'delete-all';\nexport type KeystoneReplenishStrategy =\n | typeof KEYSTONE_REPLENISH_STRATEGY_TOP_UP\n | typeof KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL\n | typeof KEYSTONE_REPLENISH_STRATEGY_CONSUME\n | typeof KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL\n ;\n/**\n * @see {@link KeystonePoolBehavior.replenish}\n */\nexport const KeystoneReplenishStrategy = {\n /**\n * replaces each used challenge, \"topping up\" the pool to the pool's size\n */\n topUp: KEYSTONE_REPLENISH_STRATEGY_TOP_UP,\n /**\n * replaces the entire pool with the new challenges\n */\n replaceAll: KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL,\n /**\n * do not replenish, only consume\n *\n * ## intent\n * adding this for revocation, though we have added deleteAll for this now.\n * Leaving it in.\n */\n consume: KEYSTONE_REPLENISH_STRATEGY_CONSUME,\n /**\n * Deletes ALL challenges in the pool, regardless of how many were used.\n * The \"Nuclear Option\" for revocation.\n */\n deleteAll: KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL,\n} satisfies { [key: string]: KeystoneReplenishStrategy };\nexport const KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES = Object.values(KeystoneReplenishStrategy);\nexport function isKeystoneReplenishStrategy(x: any): x is KeystoneReplenishStrategy {\n return typeof x === 'string' && KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES.includes(x as any);\n}\n// #endregion KeystoneReplenishStrategy\n\nexport interface KeystonePoolBehavior {\n /**\n * Target number of challenges to maintain in the pool.\n */\n size: number;\n\n /**\n * How do we fill the void left by consumed challenges?\n *\n * @see {@link KeystoneReplenishStrategy} individual members for information\n * on each one.\n */\n replenish: KeystoneReplenishStrategy;\n\n /**\n * Minimum number of challenges to consume from the \"front\" (oldest) of the pool.\n * Mitigates sequence prediction attacks if high, allows strictly ordered audit if used alone.\n */\n selectSequentially: number;\n\n /**\n * Minimum number of challenges to consume randomly from the remainder.\n * Mitigates pre-computation attacks on the sequence.\n */\n selectRandomly: number;\n\n /**\n * Number of hex characters from the Target's Gib to match.\n * @default 0\n */\n targetBindingChars: number;\n}\n\nexport interface KeystonePoolConfigBase {\n /**\n * The ID of the pool this config belongs to.\n */\n id: string;\n\n type: KeystoneChallengeType;\n /**\n * Unique salt for this pool's derivation path from the Master Secret.\n */\n salt: string;\n behavior: KeystonePoolBehavior;\n /**\n * The list of Verbs (primitive ibGib addresses) this pool is authorized to sign.\n * e.g. [\"revoke^gib\", \"admin^gib\"]\n *\n * If undefined or empty, this pool is considered a \"General/Default\" pool\n * and can sign any verb NOT explicitly claimed by another pool (implementation detail of selection)\n * or simply any verb at all (permissive).\n *\n * For V1 Security: If this is set, Validation MUST enforce it.\n */\n allowedVerbs: string[];\n}\n\nexport interface KeystonePoolConfig_HashV1 extends KeystonePoolConfigBase {\n type: typeof KeystoneChallengeType.hash_reveal_v1;\n algo: HashAlgorithm;\n rounds: number;\n}\n\nexport type KeystonePoolConfig = KeystonePoolConfig_HashV1;\n\n// ===========================================================================\n// CHALLENGES (Public Puzzles)\n// ===========================================================================\n\nexport interface KeystoneChallengeBase {\n type: KeystoneChallengeType;\n}\n\nexport interface KeystoneChallenge_HashV1 extends KeystoneChallengeBase {\n id: string;\n type: typeof KeystoneChallengeType.hash_reveal_v1;\n /**\n * The hash that must be matched by the solution.\n */\n hash: string;\n}\n\nexport type KeystoneChallenge = KeystoneChallenge_HashV1;\n\n// ===========================================================================\n// SOLUTIONS (Private Answers revealed in Proofs)\n// ===========================================================================\n\nexport interface KeystoneSolutionBase {\n type: KeystoneChallengeType;\n /**\n * The ID of the pool this solution comes from.\n */\n poolId: string;\n /**\n * The ID of the specific challenge being solved.\n */\n challengeId: string;\n}\n\nexport interface KeystoneSolution_HashV1 extends KeystoneSolutionBase {\n type: 'hash-reveal-v1';\n /**\n * The Pre-image value.\n */\n value: string;\n}\n\nexport type KeystoneSolution = KeystoneSolution_HashV1;\n\n// ===========================================================================\n// HIGH-LEVEL STRUCTURES\n// ===========================================================================\n\n/**\n * A container for a set of challenges.\n */\nexport interface KeystoneChallengePool {\n /**\n * Unique ID (e.g. \"default\", \"admin\").\n */\n id: string;\n\n /**\n * Parameterization of this pool.\n *\n * Signing and validating this pool must observe this config.\n */\n config: KeystonePoolConfig;\n\n /**\n * Default claim values for this pool.\n * Useful for \"verb-stones\".\n */\n defaultClaim?: Partial<KeystoneClaim>;\n\n /**\n * The currently active challenges.\n * Key: The unique Challenge ID (e.g. \"poolSalt_0\").\n */\n challenges: { [challengeId: string]: KeystoneChallenge };\n\n /**\n * Explicit Buckets for Target Binding.\n * Key: Hex Character ('0'-'f').\n * Value: Array of Challenge IDs that satisfy this bucket.\n * Note: A single ID may appear in multiple buckets (Coverage Strategy).\n */\n bindingMap: { [hexChar: string]: string[] };\n\n /**\n * If true, this pool's secrets are NOT derived from the Keystone's\n * primary Master Secret. They are held by an external entity.\n *\n * ## intent\n *\n * The driving use case for this is signing in with a server \"super node\"\n * and giving that node the ability to sign on behalf of the user. This is a\n * common pattern in SSO-type workflows.\n */\n isForeign?: boolean;\n\n /**\n * Arbitrary metadata for the wallet/user to identify the pool.\n * e.g. { delegate: \"PrimaryServer\", purpose: \"SSO\" }\n *\n * ## intent\n *\n * The driving use case for this is signing in with a server \"super node\"\n * and giving that node the ability to sign on behalf of the user. This is a\n * common pattern in SSO-type workflows.\n */\n metadata?: any;\n}\n\n/**\n * Describes the specific privilege that the evolution of the keystone\n * authorizes.\n */\nexport interface KeystoneClaim {\n /**\n * what action/ability does the claim make?\n *\n * @see {@link KeystoneVerb} and all of its members for just a list of some\n * common verbs. But really, this can be any string.\n */\n verb: string;\n /**\n * What specific ibgib does this claim relate to?\n *\n * For example, if we are signing a keystone to witness some specific ibgib\n * itself, similar to the most conventional use of digital signatures, then\n * this will be the address of that ibgib.\n */\n target: IbGibAddr;\n /**\n * What limitations are narrowed down to beyond just target + verb?\n */\n scope?: string;\n}\n\n/**\n * Authorization Proof.\n */\nexport interface KeystoneProof {\n id?: string;\n\n /**\n * The claim being made.\n */\n claim: Partial<KeystoneClaim>;\n\n /**\n * The solutions required to validate this claim.\n */\n solutions: KeystoneSolution[];\n\n /**\n * The list of specific Challenge IDs that were mandatorily requested\n * by the verifier/context during the signing process.\n * Essential for deterministic validation.\n */\n requiredChallengeIds?: string[];\n}\n\n/**\n * Revocation Context.\n */\nexport interface KeystoneRevocationInfo {\n reason: string;\n proof: KeystoneProof;\n}\n\n// ===========================================================================\n// TOP LEVEL IBGIB DATA\n// ===========================================================================\n\nexport interface KeystoneIb_V1 {\n atom: typeof KEYSTONE_ATOM;\n}\n\nexport interface KeystoneData_V1 extends IbGibData_V1 {\n /**\n * The pools containing the FUTURE challenges.\n * (Always topped up in V1 implementation).\n */\n challengePools: KeystoneChallengePool[];\n\n /**\n * The proofs authorizing THIS frame's evolution.\n */\n proofs: KeystoneProof[];\n\n /**\n * If present, this Keystone is dead.\n */\n revocationInfo?: KeystoneRevocationInfo;\n\n /**\n * Ephemeral details specific to this frame's creation context.\n * Meant to be observed on this frame, but NOT automatically carried forward\n * to the next frame's data during evolution.\n */\n frameDetails?: any;\n\n /**\n * Aggregated state of the Keystone identity up to this frame.\n * Acts as a snapshot to avoid walking the entire timeline.\n */\n checkpointDetails?: any;\n}\n\nexport interface KeystoneRel8ns_V1 extends IbGibRel8ns_V1 {\n // Standard ibGib relations (ancestor, past, etc.)\n // Specific hard-links for composite keystones go here later.\n}\n\nexport interface KeystoneIbGib_V1 extends IbGib_V1<KeystoneData_V1, KeystoneRel8ns_V1> {\n data: KeystoneData_V1;\n rel8ns: KeystoneRel8ns_V1;\n}\n\nexport interface DeterministicResult {\n /**\n * The Set of IDs that MUST be present in the solution.\n * Includes Alice's Demands + Target Binding Matches + FIFO.\n */\n mandatoryIds: Set<string>;\n\n /**\n * The IDs remaining in the pool that are valid candidates for\n * the Random/Stochastic step.\n */\n availableIds: string[];\n}\n", "import { HashAlgorithm } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { KeystoneReplenishStrategy } from \"./keystone-types.mjs\";\n\nexport const KEYSTONE_ATOM = \"keystone\";\nexport const KEYSTONE_POOL_ID_REGEXP = /^\\w[\\w\\-.]*$/;\n/**\n * arbitrary 64 limit? only letters characters good\n */\nexport const KEYSTONE_SALT_REGEXP = /^[a-zA-Z0-9]{1,64}$/;\n/**\n * arbitrary right now. don't want an easy DoS. this may still be too high.\n */\nexport const KEYSTONE_HASH_MAX_ROUNDS = 1_000;\n\n// #region KeystoneVerb enum\n/**\n * @see {@link KeystoneVerb.REVOKE}\n */\nexport const KEYSTONE_VERB_REVOKE = \"revoke\";\n/**\n * @see {@link KeystoneVerb.MANAGE}\n */\nexport const KEYSTONE_VERB_MANAGE = \"manage\";\n/**\n * @see {@link KeystoneVerb.SIGN}\n */\nexport const KEYSTONE_VERB_SIGN = \"sign\";\nexport type KeystoneVerb =\n | typeof KEYSTONE_VERB_REVOKE\n | typeof KEYSTONE_VERB_MANAGE\n | typeof KEYSTONE_VERB_SIGN;\n\n/**\n * Verbs that describe actions that can be authorized by a Keystone.\n */\nexport const KeystoneVerb = {\n /**\n * The specific ibGib address for the 'revoke' verb.\n * Used in Claims to indicate the Keystone should be considered dead.\n */\n REVOKE: KEYSTONE_VERB_REVOKE,\n /**\n * The meta-verb used to authorize structural changes to the Keystone,\n * specifically adding or removing challenge pools.\n *\n * \"Root access\" to the identity.\n *\n * Basically, this is the verb for the \"admin\" pool.\n *\n * todo: add a separate \"add pool\" verb\n * todo: add a one-time mechanism that limits pool use per verb.\n */\n MANAGE: KEYSTONE_VERB_MANAGE,\n /**\n * This is the least of all privileges that can actually evolve a keystone.\n */\n SIGN: KEYSTONE_VERB_SIGN,\n} satisfies { [key: string]: KeystoneVerb };\nexport const KEYSTONE_VERB_VALID_VALUES = Object.values(KeystoneVerb);\nexport function isKeystoneVerb(value: string): value is KeystoneVerb {\n return KEYSTONE_VERB_VALID_VALUES.includes(value as KeystoneVerb);\n}\n// #endregion KeystoneVerb enum\n\n/**\n * Some standard pool IDs can be conventionally named after their primary verb,\n * but this is not a requirement.\n */\nexport const POOL_ID_REVOKE = KEYSTONE_VERB_REVOKE;\nexport const POOL_ID_MANAGE = KEYSTONE_VERB_MANAGE;\nexport const POOL_ID_DEFAULT = \"default\";\nexport const POOL_ID_DELEGATE = \"delegate\";\n/**\n * **THESE SHOULD ONLY BE USED IN TEMPORARY/SESSION KEYSTONES.**\n * _this is because a receiver could intercept the stone, DoS participants and\n * then take over a stone._\n *\n * transition pools are used as a temporary mechanism to create one-time management pools for delegates to create their own pools.\n */\nexport const POOL_ID_TRANSITION = \"transition\";\n\nexport const KEYSTONE_CONFIG_DEFAULT_SIZE = 200;\nexport const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL = 2;\nexport const KEYSTONE_CONFIG_DEFAULT_RANDOM = 2;\nexport const KEYSTONE_CONFIG_DEFAULT_BINDING = 5;\nexport const KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY = KeystoneReplenishStrategy.topUp;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM = HashAlgorithm.sha_256;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS = 1;\n\nexport const KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY = 2000;\nexport const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY = 5;\nexport const KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY = 5;\nexport const KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY = 16;\nexport const KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY = KeystoneReplenishStrategy.replaceAll;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY = HashAlgorithm.sha_512;\nexport const KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY = 10;\n/**\n * the checkpointing mechanism will do a checkpoint every [this number] of\n * keystone frame evolutions.\n */\nexport const KEYSTONE_CHECKPOINT_FREQUENCY = 50;\n", "import {\n KeystonePoolConfigBase,\n KeystoneChallengeBase,\n KeystoneSolutionBase\n} from '../keystone-types.mjs';\n\n/**\n * Abstract base class for all Keystone Challenge Strategies.\n *\n * @template TConfig The specific configuration interface (e.g. HashV1).\n * @template TChallenge The specific public challenge interface.\n * @template TSolution The specific private solution interface.\n */\nexport abstract class KeystoneStrategy<\n TConfig extends KeystonePoolConfigBase,\n TChallenge extends KeystoneChallengeBase,\n TSolution extends KeystoneSolutionBase\n> {\n constructor(protected config: TConfig) {}\n\n /**\n * Derives the secret specific to this pool from the master keystone secret.\n * This isolates the pool so the master secret is never used directly\n * in challenge generation.\n */\n abstract derivePoolSecret({\n masterSecret\n }: {\n masterSecret: string\n }): Promise<string>;\n\n /**\n * Generates the private solution (Pre-image) for a specific challenge ID.\n *\n * @returns The concrete solution object (not just the value string).\n */\n abstract generateSolution({\n poolSecret,\n poolId,\n challengeId,\n }: {\n poolSecret: string;\n poolId: string;\n challengeId: string;\n }): Promise<TSolution>;\n\n /**\n * Generates the public challenge from a given solution.\n * Used when creating the pool (Top Up) or verifying a solution.\n */\n abstract generateChallenge({\n solution,\n }: {\n solution: TSolution;\n }): Promise<TChallenge>;\n\n /**\n * Validates that a given solution mathematically solves the given challenge.\n *\n * @returns true if valid, false otherwise.\n */\n abstract validateSolution({\n solution,\n challenge,\n }: {\n solution: TSolution;\n challenge: TChallenge;\n }): Promise<boolean>;\n}\n\nexport type KeystoneStrategyAny = KeystoneStrategy<any,any,any>;\n", "/**\r\n * KDF Strategy Constants\r\n *\r\n * Defines available key derivation function strategies.\r\n */\r\n\r\n// #region KdfStrategy\r\nexport const KDF_STRATEGY_RECURSIVE_SALT_WRAP = 'recursive-salt-wrap';\r\nexport type KdfStrategy =\r\n | typeof KDF_STRATEGY_RECURSIVE_SALT_WRAP\r\n ;\r\n\r\n/**\r\n * Available KDF strategies for deriving keys from master secrets.\r\n *\r\n * - `recursive-salt-wrap`: Hash(salt + current + salt) ^ rounds\r\n * Used by KeystoneStrategy_HashRevealV1 for pool secret derivation\r\n */\r\nexport const KdfStrategy = {\r\n /**\r\n * Recursive salt wrap strategy: Hash(salt + current + salt) ^ rounds\r\n *\r\n * This is the primary strategy used by keystones for deriving pool secrets\r\n * from master secrets with configurable rounds for key stretching.\r\n */\r\n recursive_salt_wrap: KDF_STRATEGY_RECURSIVE_SALT_WRAP,\r\n} satisfies { [key: string]: KdfStrategy };\r\n\r\nexport const KDF_STRATEGY_VALID_VALUES = Object.values(KdfStrategy);\r\n\r\nexport function isValidKdfStrategy(strategy: string): strategy is KdfStrategy {\r\n return KDF_STRATEGY_VALID_VALUES.includes(strategy as KdfStrategy);\r\n}\r\n// #endregion KdfStrategy\r\n", "import { extractErrorMsg, hash, HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\r\n\r\nimport { GLOBAL_LOG_A_LOT } from '../../core-constants.mjs';\r\nimport { KDF_STRATEGY_RECURSIVE_SALT_WRAP, KDF_STRATEGY_VALID_VALUES, KdfStrategy } from './kdf-constants.mjs';\r\nimport { DeriveKeyParams, KdfOptions_RecursiveSaltWrap } from './kdf-types.mjs';\r\n\r\nconst logalot = GLOBAL_LOG_A_LOT;\r\n\r\n/**\r\n * Derive a key from a master secret using the specified KDF strategy\r\n *\r\n * This is the main dispatch function for all KDF operations. It routes to the\r\n * appropriate strategy implementation based on `kdfOpts.strategy`.\r\n *\r\n * @param params - Derivation parameters including master secret and KDF options\r\n * @returns Derived key\r\n *\r\n * @example\r\n * ```typescript\r\n * const derivedKey = await deriveKey({\r\n * masterSecret: 'my-strong-password',\r\n * kdfOpts: {\r\n * strategy: KdfStrategy.recursiveSaltWrap,\r\n * salt: 'pool-identifier',\r\n * rounds: 10000,\r\n * algorithm: 'SHA-256'\r\n * }\r\n * });\r\n * ```\r\n */\r\nexport async function deriveKey({\r\n masterSecret,\r\n kdfOpts\r\n}: DeriveKeyParams): Promise<string> {\r\n const lc = `[${deriveKey.name}]`;\r\n try {\r\n if (logalot) { console.log(`${lc} starting... (I: 268e87ec311874ee6822bf459c5a5426)`); }\r\n\r\n const strategy = kdfOpts.strategy;\r\n\r\n switch (strategy) {\r\n case KdfStrategy.recursive_salt_wrap:\r\n return await kdf_recursiveSaltWrap({\r\n masterSecret,\r\n salt: kdfOpts.salt,\r\n rounds: kdfOpts.rounds,\r\n algorithm: kdfOpts.algorithm\r\n });\r\n default:\r\n throw new Error(`Unknown KDF strategy: ${strategy}. valid values: ${KDF_STRATEGY_VALID_VALUES.join(', ')} (E: c81258e9d9481eb0f88385a825193226)`);\r\n }\r\n\r\n } catch (error) {\r\n console.error(`${lc} ${extractErrorMsg(error)}`);\r\n throw error;\r\n } finally {\r\n if (logalot) { console.log(`${lc} complete.`); }\r\n }\r\n}\r\n\r\n/**\r\n * Recursive Salt Wrap KDF Strategy\r\n *\r\n * Derives a key by recursively applying: Hash(salt + current + salt) for N rounds\r\n *\r\n * This is the strategy used by KeystoneStrategy_HashRevealV1 for deriving pool secrets.\r\n *\r\n * @param masterSecret - The initial secret/password to derive from\r\n * @param salt - Salt value to wrap around the secret\r\n * @param rounds - Number of hash iterations (key stretching)\r\n * @param algorithm - Hash algorithm to use (default: SHA-256)\r\n * @returns Derived key\r\n */\r\nexport async function kdf_recursiveSaltWrap({\r\n masterSecret,\r\n salt,\r\n rounds,\r\n algorithm = HashAlgorithm.sha_256,\r\n}: {\r\n masterSecret: string;\r\n salt: string;\r\n rounds: number;\r\n algorithm?: HashAlgorithm;\r\n}): Promise<string> {\r\n const lc = `[${kdf_recursiveSaltWrap.name}]`;\r\n try {\r\n if (logalot) { console.log(`${lc} starting... (I: 850868e50aba82ff28c77da8169e4c26)`); }\r\n\r\n let current = masterSecret;\r\n\r\n for (let i = 0; i < rounds; i++) {\r\n current = await hash({\r\n s: `${salt}${current}${salt}`,\r\n algorithm\r\n });\r\n }\r\n\r\n return current;\r\n } catch (error) {\r\n console.error(`${lc} ${extractErrorMsg(error)}`);\r\n throw error;\r\n } finally {\r\n if (logalot) { console.log(`${lc} complete.`); }\r\n }\r\n}\r\n", "import { hash } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { KeystoneStrategy } from '../keystone-strategy.mjs';\nimport {\n KeystonePoolConfig_HashV1, KeystoneChallenge_HashV1, KeystoneSolution_HashV1\n} from '../../keystone-types.mjs';\nimport { kdf_recursiveSaltWrap } from '../../kdf/kdf-helpers.mjs';\n\n/**\n * The concrete implementation of the \"Salted Wrap\" Hash Reveal strategy.\n */\nexport class KeystoneStrategy_HashRevealV1 extends KeystoneStrategy<\n KeystonePoolConfig_HashV1,\n KeystoneChallenge_HashV1,\n KeystoneSolution_HashV1\n> {\n\n /**\n * Derives Pool Secret = Hash(PoolSalt + MasterSecret + PoolSalt) ^ Rounds\n */\n override async derivePoolSecret({\n masterSecret\n }: {\n masterSecret: string\n }): Promise<string> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.derivePoolSecret.name}]`;\n try {\n const { salt, rounds, algo } = this.config;\n\n return await kdf_recursiveSaltWrap({\n masterSecret,\n salt,\n rounds,\n algorithm: algo\n });\n } catch (error) {\n console.error(`${lc} Error deriving pool secret: ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Solution Value = Hash(IndexSalt + PoolSecret + IndexSalt) ^ Rounds\n */\n override async generateSolution({\n poolSecret,\n poolId,\n challengeId,\n }: {\n poolSecret: string;\n poolId: string;\n challengeId: string;\n }): Promise<KeystoneSolution_HashV1> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.generateSolution.name}]`;\n try {\n const { rounds, algo } = this.config;\n\n // The Index Salt is the unique identifier for this slot\n const indexSalt = challengeId;\n\n let current = poolSecret;\n for (let i = 0; i < rounds; i++) {\n current = await hash({\n s: `${indexSalt}${current}${indexSalt}`,\n algorithm: algo\n });\n }\n\n return {\n type: 'hash-reveal-v1',\n poolId,\n challengeId,\n value: current\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Challenge Hash = Hash(IndexSalt + SolutionValue + IndexSalt) ^ Rounds\n */\n override async generateChallenge({\n solution,\n }: {\n solution: KeystoneSolution_HashV1;\n }): Promise<KeystoneChallenge_HashV1> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.generateChallenge.name}]`;\n try {\n const { rounds, algo } = this.config;\n const { challengeId, value } = solution;\n const indexSalt = challengeId;\n\n let current = value;\n for (let i = 0; i < rounds; i++) {\n current = await hash({\n s: `${indexSalt}${current}${indexSalt}`,\n algorithm: algo\n });\n }\n\n return {\n id: challengeId,\n type: 'hash-reveal-v1',\n hash: current\n };\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Re-generates the challenge from the candidate solution and compares.\n */\n override async validateSolution({\n solution,\n challenge,\n }: {\n solution: KeystoneSolution_HashV1;\n challenge: KeystoneChallenge_HashV1;\n }): Promise<boolean> {\n const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.validateSolution.name}]`;\n try {\n // 1. Check Type Compatibility\n if (solution.type !== 'hash-reveal-v1' || challenge.type !== 'hash-reveal-v1') {\n console.warn(`${lc} Mismatched types provided.`);\n return false;\n }\n\n // 2. Generate the expected challenge hash from the solution provided\n const calculatedChallenge = await this.generateChallenge({ solution });\n\n // 3. Compare\n return calculatedChallenge.hash === challenge.hash;\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n return false; // Fail closed\n }\n }\n}\n", "import {\n KeystonePoolConfig\n} from '../keystone-types.mjs';\nimport { KeystoneStrategyAny } from './keystone-strategy.mjs';\nimport { KeystoneStrategy_HashRevealV1 } from './hash-reveal-v1/hash-reveal-v1.mjs';\n\nexport class KeystoneStrategyFactory {\n\n /**\n * Instantiates the appropriate concrete KeystoneStrategy based on the\n * provided configuration type.\n *\n * @param config The configuration object for the pool (contains 'type').\n * @returns An instance of the specific strategy class.\n */\n static create({\n config,\n }: {\n config: KeystonePoolConfig,\n }): KeystoneStrategyAny {\n const lc = `[${KeystoneStrategyFactory.name}.create]`;\n try {\n switch (config.type) {\n case 'hash-reveal-v1':\n return new KeystoneStrategy_HashRevealV1(config);\n\n default:\n throw new Error(`Unknown strategy type: ${(config as any).type} (E: 4e3c2f7129a241c1b687555e678c1065)`);\n }\n } catch (error) {\n console.error(`${lc} ${error.message}`);\n throw error;\n }\n }\n}\n", "import { extractErrorMsg, hash, HashAlgorithm, pretty } from \"@ibgib/helper-gib/dist/helpers/utils-helper.mjs\";\nimport { GIB } from \"@ibgib/ts-gib/dist/V1/constants.mjs\";\nimport { Ib, TransformResult } from \"@ibgib/ts-gib/dist/types.mjs\";\nimport { getIbAndGib, getIbGibAddr } from \"@ibgib/ts-gib/dist/helper.mjs\";\nimport { validateIbGibIntrinsically } from \"@ibgib/ts-gib/dist/V1/validate-helper.mjs\";\nimport { mut8 } from \"@ibgib/ts-gib/dist/V1/transforms/mut8.mjs\";\nimport { Factory_V1 } from \"@ibgib/ts-gib/dist/V1/factory.mjs\";\nimport { getGib } from \"@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs\";\n\nimport { GLOBAL_LOG_A_LOT } from \"../core-constants.mjs\";\nimport { KEYSTONE_ATOM, KEYSTONE_HASH_MAX_ROUNDS, KEYSTONE_POOL_ID_REGEXP, KEYSTONE_SALT_REGEXP } from \"./keystone-constants.mjs\";\nimport {\n KeystoneData_V1, KeystoneIbGib_V1, KeystoneIb_V1, KeystoneChallengePool,\n DeterministicResult, KeystoneProof, KeystonePoolConfig,\n KeystoneReplenishStrategy, KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES,\n KeystoneClaim, KeystoneSolution,\n KeystoneChallengeType,\n KEYSTONE_CHALLENGE_TYPE_VALID_VALUES,\n KeystonePoolConfig_HashV1,\n} from \"./keystone-types.mjs\";\nimport { MetaspaceService } from \"../witness/space/metaspace/metaspace-types.mjs\";\nimport { IbGibSpaceAny } from \"../witness/space/space-base-v1.mjs\";\nimport { KeystoneStrategyFactory } from \"./strategy/keystone-strategy-factory.mjs\";\nimport { getDependencyGraph } from \"../common/other/graph-helper.mjs\";\nimport { getIbGibsFromCache_fallbackToSpaces, getTimelinesGroupedByTjp, splitPerTjpAndOrDna } from \"../common/other/ibgib-helper.mjs\";\nimport { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from \"@ibgib/ts-gib/dist/V1/types.mjs\";\nimport { getLatestAddrs } from \"../witness/space/space-helper.mjs\";\nimport { FlatIbGibGraph } from \"../common/other/graph-types.mjs\";\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * space-delimited keystone ib containing select keystone metadata.\n *\n * NOTE: This must match {@link parseKeystoneIb}\n * @see {@link KeystoneIb_V1}\n */\nexport async function getKeystoneIb({\n keystoneData,\n}: {\n keystoneData: KeystoneData_V1,\n}): Promise<Ib> {\n const lc = `[${getKeystoneIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c3022a146faac9730154f34d1439a225)`); }\n\n const atom = KEYSTONE_ATOM;\n\n const ib = [\n atom,\n ].join(' ');\n\n return ib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * NOTE: This must match {@link getKeystoneIb}\n * @see {@link KeystoneIb_V1}\n */\nexport async function parseKeystoneIb({\n ib,\n}: {\n ib: Ib,\n}): Promise<KeystoneIb_V1> {\n const lc = `[${parseKeystoneIb.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 73cb6832984255ed48b2f44db6a21e25)`); }\n const [\n atom\n ] = ib.split(' ');\n\n if (atom !== KEYSTONE_ATOM) {\n throw new Error(`invalid keystone ib. atom found in ib (${atom}) does not match keystone atom (${KEYSTONE_ATOM}) (E: 79b3d587824c4271b6e60acc76e0c825)`);\n }\n\n return {\n atom,\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * The Policy Engine.\n * Calculates exactly which challenges MUST be consumed based on config and demands.\n * Enforces STRICT DISTINCTNESS (No double-dipping).\n */\nexport function getDeterministicRequirements({\n pool,\n requiredChallengeIds,\n targetAddr\n}: {\n pool: KeystoneChallengePool;\n requiredChallengeIds?: string[];\n targetAddr?: string;\n}): DeterministicResult {\n const behavior = pool.config.behavior;\n const mandatory = new Set<string>();\n\n // Start with all available IDs.\n // We assume Object.keys respects insertion order (ES2015+), crucial for FIFO.\n let available = Object.keys(pool.challenges);\n\n // ---------------------------------------------------------\n // 1. Alice's Demands (Explicit Requirements)\n // ---------------------------------------------------------\n if (requiredChallengeIds && requiredChallengeIds.length > 0) {\n for (const id of requiredChallengeIds) {\n if (!pool.challenges[id]) {\n throw new Error(`(UNEXPECTED) Required challenge ID not found in pool: ${id} (E: 10c5619d80d8cf6cc84ffbf8be0dbc25)`);\n }\n // Strict: Consume it.\n if (!available.includes(id)) {\n // Should be caught by check above, but handles duplicates in 'demands'\n continue;\n }\n mandatory.add(id);\n }\n // Remove from available pool\n available = available.filter(id => !mandatory.has(id));\n }\n\n // ---------------------------------------------------------\n // 2. Target Binding (Explicit Buckets)\n // ---------------------------------------------------------\n if (behavior.targetBindingChars > 0 && targetAddr) {\n const { gib } = getIbAndGib({ ibGibAddr: targetAddr });\n if (gib) {\n // Get required hex prefixes (e.g. 'a', 'b', 'c', '1')\n const prefixes = gib !== GIB ?\n gib.substring(0, behavior.targetBindingChars).toLowerCase() :\n 'abc'; // arbitrary for primitive binding target ibgib\n\n for (const char of prefixes) {\n // Look in the Explicit Bucket\n const bucket = pool.bindingMap[char] || [];\n\n // Find the first ID in this bucket that is still in 'available'\n const match = bucket.find(id => available.includes(id));\n\n if (!match) {\n throw new Error(`Entropy Exhaustion. Cannot satisfy binding for char '${char}'. (E: 341b95dc3a58be3e083d1d9c4a0c4925)`);\n }\n\n // Strict: Consume it.\n mandatory.add(match);\n available = available.filter(id => id !== match);\n }\n }\n }\n\n // ---------------------------------------------------------\n // 3. FIFO (Sequential)\n // ---------------------------------------------------------\n if (behavior.selectSequentially > 0) {\n // Take the first N from the remaining available list\n if (available.length < behavior.selectSequentially) {\n console.error(`[getDeterministicRequirements] Entropy Exhaustion! AvailableCount: ${available.length}, Required Seq: ${behavior.selectSequentially}. Available IDs: ${available.join(',')}`);\n throw new Error(`Entropy Exhaustion. Insufficient challenges for FIFO requirement. (E: 9efa88003e1d5eccb837c85154ee5625)`);\n }\n\n const fifoIds = available.slice(0, behavior.selectSequentially);\n fifoIds.forEach(id => mandatory.add(id));\n\n // Remove from available\n available = available.slice(behavior.selectSequentially);\n }\n\n return { mandatoryIds: mandatory, availableIds: available };\n}\n\n/**\n * Helper to update the Binding Map when adding new Challenge IDs.\n * Uses \"Implicit Bucketing\" (ID start char) but can be extended for full coverage.\n */\nexport function addToBindingMap(\n map: { [char: string]: string[] },\n challengeId: string\n): void {\n const firstChar = challengeId.charAt(0).toLowerCase();\n // Validate it is hex\n if (/[0-9a-f]/.test(firstChar)) {\n if (!map[firstChar]) { map[firstChar] = []; }\n map[firstChar].push(challengeId);\n\n // OPTIONAL: Implement Full Coverage Strategy here?\n // e.g. map[challengeId[1]].push(challengeId) ...\n // For V1, we stick to Native/Implicit bucket (Index 0).\n } else {\n throw new Error(`invalid challengeId (${challengeId}). Must start with a hex character. (E: c96ed8460de89e28c801370a0f07f826)`);\n }\n}\n\n/**\n * Helper to clean up Binding Map when removing IDs.\n */\nexport function removeFromBindingMap(\n map: { [char: string]: string[] },\n challengeId: string\n): void {\n // Since we don't know exactly which buckets an ID is in (if we did multi-bucket),\n // we strictly should scan all. For V1 Native, we check first char.\n // SAFE IMPLEMENTATION: Scan all buckets.\n for (const key of Object.keys(map)) {\n map[key] = map[key].filter(id => id !== challengeId);\n }\n}\n\n/**\n * Selects the specific pool to use for an operation based on ID, filter criteria, or verb authorization.\n *\n * @returns The matching KeystoneChallengePool\n * @throws If no pool matches or if multiple pools match but one was expected.\n */\nexport function resolveTargetPool({\n pools,\n poolId,\n poolFilter,\n verb,\n}: {\n pools: KeystoneChallengePool[];\n /**\n * Explicit ID of the pool to use.\n */\n poolId?: string;\n /**\n * Optional predicate to find a pool.\n * Useful for finding delegates via metadata.\n */\n poolFilter?: (pool: KeystoneChallengePool) => boolean;\n /**\n * The verb being performed (e.g. 'revoke', 'manage', 'post').\n * Used for authorization checks and auto-resolution.\n */\n verb?: string;\n}): KeystoneChallengePool {\n const lc = `[resolveTargetPool]`;\n try {\n let pool: KeystoneChallengePool | undefined;\n\n if (poolId) {\n // 1. Explicit ID Strategy\n pool = pools.find(p => p.id === poolId);\n if (!pool) { throw new Error(`Pool not found with ID: ${poolId} (E: 4a2b17428515c1e82813158581898125)`); }\n } else if (poolFilter) {\n // 2. Filter Strategy\n const matches = pools.filter(poolFilter);\n if (matches.length === 0) { throw new Error(`No pool matched the provided filter. (E: 5b3c27428515c1e82813158581898125)`); }\n // For now, we take the first match. In future, might want to be strict about uniqueness.\n pool = matches[0];\n } else {\n // 3. Auto-Resolution by Verb Strategy\n if (!verb) { throw new Error(`Cannot auto-resolve pool without a verb. (E: 6c4d37428515c1e82813158581898125)`); }\n\n // Priority A: Look for Specific Match (Pool explicitly lists this verb)\n pool = pools.find(p =>\n p.config.allowedVerbs && p.config.allowedVerbs.includes(verb)\n );\n\n // Priority B: Look for General/Default (No restrictions / Wildcard)\n if (!pool) {\n pool = pools.find(p =>\n !p.config.allowedVerbs || p.config.allowedVerbs.length === 0\n );\n }\n\n if (!pool) { throw new Error(`No suitable pool found for verb: ${verb} (E: 7d5e47428515c1e82813158581898125)`); }\n }\n\n // 4. Authorization Check (Applies to all strategies if verb is present)\n if (verb && pool.config.allowedVerbs && pool.config.allowedVerbs.length > 0) {\n if (!pool.config.allowedVerbs.includes(verb)) {\n throw new Error(`Pool ${pool.id} is not authorized for verb: ${verb} (E: 8e6f57428515c1e82813158581898125)`);\n }\n }\n\n return pool;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Calculates the complete list of Challenge IDs to solve for a given operation.\n * Combines Deterministic requirements (Mandatory/Binding/FIFO) with Stochastic requirements.\n *\n * @returns Array of unique challenge IDs.\n */\nexport function selectChallengeIds({\n pool,\n targetAddr,\n requiredChallengeIds,\n}: {\n pool: KeystoneChallengePool;\n /**\n * The address of the target ibgib (used for binding entropy).\n */\n targetAddr?: string;\n /**\n * Explicit demands from a verifier.\n */\n requiredChallengeIds?: string[];\n}): string[] {\n const lc = `[selectChallengeIds]`;\n try {\n // 1. Get Deterministic Requirements\n const { mandatoryIds, availableIds } = getDeterministicRequirements({\n pool,\n requiredChallengeIds,\n targetAddr\n });\n\n // 2. Stochastic Selection\n const randomCount = pool.config.behavior.selectRandomly;\n const randomIds: string[] = [];\n\n if (randomCount > 0) {\n if (availableIds.length < randomCount) {\n throw new Error(`Insufficient challenges for random requirement. Need ${randomCount}, have ${availableIds.length} (E: 9f7a67428515c1e82813158581898125)`);\n }\n // Shuffle & Pick\n // Note: simple Math.random sort is sufficient for V1 stochastic selection\n // as we are just picking from valid available options.\n const shuffled = [...availableIds].sort(() => 0.5 - Math.random());\n randomIds.push(...shuffled.slice(0, randomCount));\n }\n\n // 3. Combine\n return [...mandatoryIds, ...randomIds];\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * Generates an opaque, collision-resistant ID for a challenge.\n * atow (2025/12/22) - Hash(Salt + Timestamp + Index)\n */\nexport async function generateOpaqueChallengeId({\n salt,\n timestamp,\n index\n}: {\n salt: string,\n timestamp: string,\n index: number\n}): Promise<string> {\n // Use first 16 chars of hex (64 bits) for brevity + safety.\n const raw = await hash({ s: `${salt}${timestamp}${index}` });\n return raw.substring(0, 16);\n}\n\n/**\n * Calculates the NEXT state of the Challenge Pools given a specific consumption event.\n * Handles TopUp, ReplaceAll, Consume, and ScorchedEarth strategies.\n *\n * @returns The new array of KeystoneChallengePools (including the modified one).\n */\nexport async function applyReplenishmentStrategy({\n prevPools,\n targetPoolId,\n consumedIds,\n masterSecret,\n strategy,\n config,\n}: {\n prevPools: KeystoneChallengePool[],\n targetPoolId: string,\n consumedIds: string[],\n masterSecret: string,\n /**\n * The instantiated KeystoneStrategy (e.g. HashRevealV1) used to generate new challenges.\n */\n strategy: any, // Typed as 'any' or 'KeystoneStrategyAny' to avoid circular dep if possible\n config: KeystonePoolConfig,\n}): Promise<KeystoneChallengePool[]> {\n const lc = `[applyReplenishmentStrategy]`;\n try {\n const newPools = JSON.parse(JSON.stringify(prevPools));\n const targetIdx = newPools.findIndex((p: any) => p.id === targetPoolId);\n if (targetIdx === -1) { throw new Error(`Target pool ${targetPoolId} not found in keystone data. (E: 75200388d22744838634524233772545)`); }\n const pool = newPools[targetIdx];\n\n const poolSecret = await strategy.derivePoolSecret({ masterSecret });\n const timestamp = Date.now().toString();\n\n const strategyType = config.behavior.replenish;\n\n // Clean up Binding Map for consumed IDs\n consumedIds.forEach(id => {\n if (pool.bindingMap) { removeFromBindingMap(pool.bindingMap, id); }\n });\n\n if (strategyType === KeystoneReplenishStrategy.topUp) {\n // Remove consumed\n consumedIds.forEach(id => delete pool.challenges[id]);\n\n // Add New\n for (let i = 0; i < consumedIds.length; i++) {\n const newId = await generateOpaqueChallengeId({\n salt: config.salt, timestamp, index: i\n });\n\n const solution = await strategy.generateSolution({\n poolSecret, poolId: pool.id, challengeId: newId\n });\n pool.challenges[newId] = await strategy.generateChallenge({ solution });\n\n // Update Binding Map\n if (!pool.bindingMap) { pool.bindingMap = {}; }\n addToBindingMap(pool.bindingMap, newId);\n }\n } else if (strategyType === KeystoneReplenishStrategy.replaceAll) {\n pool.challenges = {};\n pool.bindingMap = {};\n\n for (let i = 0; i < config.behavior.size; i++) {\n const newId = await generateOpaqueChallengeId({\n salt: config.salt, timestamp, index: i\n });\n const solution = await strategy.generateSolution({\n poolSecret, poolId: pool.id, challengeId: newId\n });\n pool.challenges[newId] = await strategy.generateChallenge({ solution });\n addToBindingMap(pool.bindingMap, newId);\n }\n } else if (strategyType === KeystoneReplenishStrategy.consume) {\n consumedIds.forEach(id => delete pool.challenges[id]);\n } else if (strategyType === KeystoneReplenishStrategy.deleteAll) {\n pool.challenges = {};\n pool.bindingMap = {};\n } else {\n throw new Error(`Unknown replenish strategy: ${strategyType}. Valid list: ${pretty(KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES)} (E: 0acf56f1e1486240080e11e8046d0825)`);\n }\n\n return newPools;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\n/**\n * High-level orchestration helper.\n * 1. Instantiates Strategy.\n * 2. Derives Secret.\n * 3. Solves Challenges (Generates Solutions).\n * 4. Replenishes Pool (Calculates the next state of ALL pools).\n * 5. Constructs Proof.\n *\n * @returns The resulting Proof and the full list of Next Pools.\n */\nexport async function solveAndReplenish({\n targetPoolId,\n prevPools,\n masterSecret,\n challengeIds,\n claim,\n requiredChallengeIds,\n}: {\n /**\n * The ID of the pool to use for signing.\n */\n targetPoolId: string;\n /**\n * The full list of pools from the previous Keystone frame.\n * Required to reconstruct the full state for the next frame.\n */\n prevPools: KeystoneChallengePool[];\n masterSecret: string;\n challengeIds: string[];\n claim: Partial<KeystoneClaim>;\n requiredChallengeIds?: string[];\n}): Promise<{ proof: KeystoneProof, nextPools: KeystoneChallengePool[] }> {\n const lc = `[solveAndReplenish]`;\n try {\n if (logalot) { console.log(`${lc} starting... poolId: ${targetPoolId}, ids: ${challengeIds.length}`); }\n\n const pool = prevPools.find(p => p.id === targetPoolId);\n if (!pool) { throw new Error(`Target pool not found: ${targetPoolId} (E: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6)`); }\n\n const strategy = KeystoneStrategyFactory.create({ config: pool.config });\n const poolSecret = await strategy.derivePoolSecret({ masterSecret });\n const solutions: KeystoneSolution[] = [];\n\n // 1. Solve\n for (const id of challengeIds) {\n const solution = await strategy.generateSolution({\n poolSecret, poolId: pool.id, challengeId: id,\n });\n solutions.push(solution);\n }\n\n // 2. Construct Proof\n const proof: KeystoneProof = {\n claim,\n solutions,\n requiredChallengeIds: (requiredChallengeIds && requiredChallengeIds.length > 0) ? requiredChallengeIds : undefined\n };\n\n // 3. Replenish\n const nextPools = await applyReplenishmentStrategy({\n prevPools,\n targetPoolId: pool.id,\n consumedIds: challengeIds,\n masterSecret,\n strategy,\n config: pool.config\n });\n\n return { proof, nextPools };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n}\n\nexport async function validateChallengePool_typeHashRevealV1({ pool }: {\n pool: KeystoneChallengePool;\n}): Promise<string[]> {\n const lc = `[${validateChallengePool_typeHashRevealV1.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: e2ffd568b698cc12d8c5e838d73ae726)`); }\n\n if (!pool.config) { throw new Error(`(UNEXPECTED) pool.configy falsy? (E: fcde88fe20e8004a58d7e445436bf526)`); }\n if (pool.config.type !== KeystoneChallengeType.hash_reveal_v1) {\n throw new Error(`(UNEXPECTED) pool.config.type !== KeystoneChallengeType.hash_reveal_v1? (E: e205f8872909c37168a624a9df778c26)`);\n }\n\n const errors: string[] = [];\n\n const { algo, rounds, salt, } = pool.config as KeystonePoolConfig_HashV1;\n\n const validAlgos: HashAlgorithm[] = [HashAlgorithm.sha_256];\n if (algo) {\n if (!validAlgos.includes(algo)) {\n errors.push(`${lc} invalid hash algorithm (${algo}). Must be one of ${validAlgos}. (E: a22399ca3a68e63ffcc7507699be5826)`);\n }\n } else {\n errors.push(`${lc} algorithm required. (E: 8cd6bfb0590862b9bae24d98d2cf3826)`)\n }\n\n if (rounds && typeof rounds === 'number' && Number.isInteger(rounds)) {\n if (rounds > KEYSTONE_HASH_MAX_ROUNDS) {\n errors.push(`${lc} rounds too high. max rounds: ${KEYSTONE_HASH_MAX_ROUNDS} (E: 31ce082f7fd88d6b58ef08a816458826)`);\n }\n } else {\n errors.push(`${lc} invalid rounds (${rounds}). must be positive integer. (E: 73c643ccda78afaf28d52a6871a9e826)`);\n }\n\n if (salt && typeof salt === 'string') {\n // no limits on this? sanity check?\n if (!KEYSTONE_SALT_REGEXP.test(salt)) {\n errors.push(`${lc} invalid salt (${salt.substring(0, 99)}). Must match regexp ${KEYSTONE_SALT_REGEXP}`);\n }\n } else {\n errors.push(`${lc} invalid salt (${salt}). must be truthy string value. (E: 564a4844ec88fc1988197ce89c381426)`);\n }\n\n return errors;\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateChallengePool({ pool }: {\n pool: KeystoneChallengePool;\n}): Promise<string[]> {\n const lc = `[${validateChallengePool.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 1a0eafc158a83d1ba8fc019d5c979a26)`); }\n const errors: string[] = [];\n\n if (pool.config) {\n // first validate common to all pools, regardless of type...\n if (pool.config.id) {\n if (!KEYSTONE_POOL_ID_REGEXP.test(pool.config.id)) {\n // not 100% that this is needed but hey\n errors.push(`${lc} pool.config.id is not formatted correctly. must pass regexp: ${KEYSTONE_POOL_ID_REGEXP.source}`);\n }\n } else {\n errors.push(`${lc} pool.config.id falsy (E: 31d7943d95f877326d5f4ea14463d626)`);\n }\n\n if (pool.config.behavior) {\n const { size } = pool.config.behavior;\n if (!size || size === 0) {\n errors.push(`${lc} invalid pool.config.behavior.size (${size}). Must be positive integer. (E: b221e36ec102bdc944552248ce8fe626)`)\n }\n // todo: more behavior checks\n } else {\n errors.push(`${lc} pool.config.behavior falsy (E: bede081c066c39732eefe2f92e296326)`)\n }\n\n // ...then do type-specific validation\n const poolType = pool.config.type;\n switch (poolType) {\n case KeystoneChallengeType.hash_reveal_v1:\n const errorsHashRevealV1 = await validateChallengePool_typeHashRevealV1({ pool });\n errorsHashRevealV1.forEach(x => errors.push(x));\n break;\n default:\n throw new Error(`(UNEXPECTED) unknown pool.config.type (${poolType})? We only implement the following at this time: ${KEYSTONE_CHALLENGE_TYPE_VALID_VALUES} (E: cce5285cf7580b8bc82172488eba2826)`);\n }\n } else {\n errors.push(`${lc} pool.config falsy. (E: 8d05c875a1d2c58018a5eaf803977d26)`);\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n\nexport async function validateGenesisKeystone({\n keystoneIbGib\n}: {\n keystoneIbGib: KeystoneIbGib_V1;\n}): Promise<string[]> {\n const lc = `[${validateGenesisKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: ec6ba82ec848b5ac3d8953e89d8d9826)`); }\n\n const errors: string[] = [];\n\n const { data, rel8ns } = keystoneIbGib;\n\n // no proofs/solutions yet\n if (data.proofs && data.proofs.length > 0) {\n errors.push(`${lc} proofs already exist on genesis keystone. (E: 7a5e15f20918f1bbd8ffb62857dcd526)`);\n }\n\n for (const pool of data.challengePools) {\n // validate each pool intrinsically (config, sanity)\n const poolErrors = await validateChallengePool({ pool });\n poolErrors.forEach(x => errors.push(x));\n\n // additionally ensure each pool has challenges. This is only on\n // this genesis keystone, as it is valid to have pool without\n // challenges after revocation\n if (!pool.challenges || Object.keys(pool.challenges).length === 0) {\n errors.push(`${lc} invalid pool (${pool.id}). pool.challenges is falsy/empty. (E: 8cd16a5416ae62a058342828be465b26)`);\n }\n }\n\n // not stated as revoked already\n if (!!data.revocationInfo) {\n errors.push(`${lc} genesis keystone already has revocationInfo. (E: e11408d0c558d0fa948efbce611ec826)`);\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Validates the transition from Prev -> Curr.\n * Enforces Cryptography AND Behavioral Policy.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n */\nexport async function validateKeystoneTransition({\n currentIbGib,\n prevIbGib,\n}: {\n currentIbGib: KeystoneIbGib_V1;\n prevIbGib: KeystoneIbGib_V1;\n}): Promise<string[]> {\n const lc = `[${validateKeystoneTransition.name}]`;\n const errors: string[] = [];\n try {\n if (!currentIbGib) {\n throw new Error(`(UNEXPECTED) currentIbGib falsy? (E: 3c0f02655fa8279e386a079ebb604b25)`);\n }\n if (!prevIbGib) { throw new Error(`(UNEXPECTED) prevIbGib falsy? (E: 0d07c812634d839c784f31b8848ba825)`); }\n\n // intrinsic validation\n const validationErrors = await validateIbGibIntrinsically({ ibGib: currentIbGib });\n if (validationErrors && validationErrors.length > 0) {\n errors.push(...validationErrors);\n }\n\n const currData = currentIbGib.data!;\n const prevData = prevIbGib.data!;\n\n // must be sequential data.n values\n // note: \"-2\" because we don't want a \"valid\" sequential data.n if we\n // have an invalid prev and a valid currDataN of 0\n const currDataN = currData.n ?? -2;\n const prevDataN = prevData.n ?? -2;\n if (currDataN < 0) {\n errors.push('invalid keystone.currData.n is undefined or null.');\n }\n if (prevDataN < 0) {\n errors.push('invalid keystone.prevData.n is undefined or null.');\n };\n if (currDataN !== (prevDataN + 1)) {\n errors.push(`keystone data.n values are not sequential. prevData.n: ${prevDataN}, currData.n: ${currDataN}. `);\n }\n\n for (const proof of currData.proofs) {\n if (proof.solutions.length === 0) {\n errors.push(`Proof ${proof.id || 'unknown'} has no solutions.`);\n continue;\n }\n\n const poolId = proof.solutions[0].poolId;\n\n // Standard Verification (Internal Pools Only)\n // The pool MUST be present in the previous frame.\n const pool = prevData.challengePools.find(p => p.id === poolId);\n if (!pool) {\n errors.push(`Proof references unknown pool: ${poolId}`);\n continue;\n }\n\n await verifyProofAgainstPool({ proof, pool, errors });\n\n } // End proof loop\n\n // Revocation Logic checks\n if (currData.revocationInfo) {\n const target = currData.revocationInfo.proof.claim.target;\n const expectedTarget = getIbGibAddr({ ibGib: prevIbGib });\n if (target !== expectedTarget) {\n errors.push(`Revocation target mismatch. Expected ${expectedTarget}, got ${target}`);\n }\n }\n\n return errors;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error; // System errors still throw\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Helper to verify a single proof against a specific pool.\n */\nexport async function verifyProofAgainstPool({\n proof,\n pool,\n errors,\n}: {\n proof: KeystoneProof;\n pool: KeystoneChallengePool;\n errors: string[];\n}): Promise<void> {\n const lc = `[${verifyProofAgainstPool.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b8f9b6085888eea2258bf579ecd5e825)`); }\n\n // 0. VERB AUTH\n if (pool.config.allowedVerbs && pool.config.allowedVerbs.length > 0) {\n if (!proof.claim.verb || !pool.config.allowedVerbs.includes(proof.claim.verb)) {\n errors.push(`Policy Violation: Pool ${pool.id} used for unauthorized verb ${proof.claim.verb}`);\n }\n }\n\n // 1. Reconstruct Deterministic Requirements\n const { mandatoryIds, availableIds } = getDeterministicRequirements({\n pool,\n requiredChallengeIds: proof.requiredChallengeIds,\n targetAddr: proof.claim.target // Not used extensively in V1 logic yet, mainly for logging/context\n });\n\n // 2. Check Mandatory\n const proofIds = new Set(proof.solutions.map(s => s.challengeId));\n for (const id of mandatoryIds) {\n if (!proofIds.has(id)) {\n errors.push(`Policy Violation: Missing mandatory challenge ${id}`);\n }\n }\n\n // 3. Stochastic\n const randomCandidates = [...proofIds].filter(id => !mandatoryIds.has(id));\n const requiredRandomCount = pool.config.behavior.selectRandomly;\n if (randomCandidates.length < requiredRandomCount) {\n errors.push(`Policy Violation: Insufficient random count. Need ${requiredRandomCount}, got ${randomCandidates.length}`);\n }\n\n // 4. Validity (Double Dip / Existence)\n for (const id of randomCandidates) {\n if (!availableIds.includes(id)) {\n errors.push(`Policy Violation: ID ${id} is invalid or double-dipped.`);\n }\n }\n\n // 5. Crypto\n const strategy = KeystoneStrategyFactory.create({ config: pool.config });\n for (const solution of proof.solutions) {\n const challenge = pool.challenges[solution.challengeId];\n if (!challenge) {\n errors.push(`Crypto Violation: Challenge ${solution.challengeId} not found in pool.`);\n } else {\n const isValid = await strategy.validateSolution({ solution, challenge });\n if (!isValid) {\n errors.push(`Crypto Violation: Solution for ${solution.challengeId} is invalid.`);\n }\n }\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function evolvePersistAndRegisterKeystone({\n prevIbGib,\n newData,\n metaspace,\n space,\n}: {\n prevIbGib: KeystoneIbGib_V1,\n newData: KeystoneData_V1\n metaspace: MetaspaceService,\n space: IbGibSpaceAny,\n}): Promise<KeystoneIbGib_V1> {\n const lc = `[${evolvePersistAndRegisterKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8b10e8920f08b7842803665834cf8925)`); }\n\n if (!prevIbGib.data) { throw new Error(`(UNEXPECTED) prevIbGib.data falsy? (E: 5e84875bf992c585b979e6c8ed5bf225)`); }\n if (prevIbGib.data.revocationInfo) { throw new Error(`Keystone has already been revoked (prevIbGib.data.revocationInfo truthy), so we cannot evolve the keystone. Keystone addr: ${getIbGibAddr({ ibGib: prevIbGib })} (E: 45d7f846556829de6b2a701838c3f825)`); }\n\n const prevData = prevIbGib.data;\n /**\n * we want to completely replace these keys, so we will remove them\n * from the data. This occurs first in the underlying mut8\n * transform.\n * @see {@link mut8}\n */\n let dataToRemove: Partial<KeystoneData_V1> | undefined = {}\n if (prevData.proofs) { dataToRemove.proofs = []; }\n if (prevData.challengePools) { dataToRemove.challengePools = []; }\n if (prevData.frameDetails) { dataToRemove.frameDetails = {}; }\n if (prevData.checkpointDetails) { dataToRemove.checkpointDetails = {}; }\n if (Object.keys(dataToRemove).length === 0) { dataToRemove = undefined; }\n\n const resMut8 = await mut8({\n src: prevIbGib,\n dataToRemove,\n dataToAddOrPatch: newData,\n // dna: false, // explicitly set to false just to show\n nCounter: true,\n });\n\n if (!!resMut8.intermediateIbGibs) { throw new Error(`(UNEXPECTED) resMut8.intermediateIbGibs truthy? I'm not sure if we expect there to be intermediateIbGibs, but I feel like we shouldn't. Pretty sure we shouldn't, definitely don't *want* them. (E: ba40d55d7c2d36d438c413886f148625)`); }\n if (!!resMut8.dnas) { throw new Error(`(UNEXPECTED) resMut8.dnas truthy? We do not want dnas with keystones. (E: 49470513d018f97d28024f4e82da3b25)`); }\n\n\n const newKeystoneIbGib = resMut8.newIbGib as KeystoneIbGib_V1;\n\n // run validation here\n const errors = await validateKeystoneTransition({\n currentIbGib: newKeystoneIbGib,\n prevIbGib,\n });\n if (errors.length > 0) {\n console.error(`${lc} Validation Failed:\\n${errors.join('\\n')}`);\n throw new Error(`(UNEXPECTED) invalid keystone after we just evolved it? Errors: ${errors.join('; ')} (E: ae2c58406c1db7687879dfb89fc1f825)`);\n }\n\n // save and register\n await metaspace.put({ ibGib: newKeystoneIbGib, space, });\n await metaspace.registerNewIbGib({ ibGib: newKeystoneIbGib, space, });\n\n return newKeystoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n/**\n * Creates a new keystone ibgib that has no dna and no past.\n */\nexport async function createKeystoneIbGibImpl({\n data,\n metaspace,\n space,\n}: {\n data: KeystoneData_V1,\n metaspace: MetaspaceService,\n space?: IbGibSpaceAny,\n}): Promise<KeystoneIbGib_V1> {\n const lc = `[${createKeystoneIbGibImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 5e32389700e9899e788cbefacef7c825)`); }\n\n space ??= await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(`(UNEXPECTED) space was falsy and we couldn't get default local user space from metaspace? (E: 9a6498cf16a8801f19ec376749742225)`); }\n\n // create the actual keystoneIbGib\n const resFirstGen = await Factory_V1.firstGen({\n parentIbGib: Factory_V1.primitive({ ib: KEYSTONE_ATOM }),\n ib: await getKeystoneIb({ keystoneData: data }),\n data,\n dna: false,\n nCounter: true,\n tjp: {\n timestamp: true,\n uuid: true,\n },\n }) as TransformResult<KeystoneIbGib_V1>;\n const keystoneIbGib = resFirstGen.newIbGib;\n\n if (!keystoneIbGib.data) { throw new Error(`(UNEXPECTED) keystoneIbGib.data falsy? We expect the data to be populated with real keystone data. (E: 38a358facdb89d16d81d48c8520d3d25)`); }\n if (!keystoneIbGib.rel8ns) { throw new Error(`(UNEXPECTED) keystoneIbGib.rel8ns falsy? we expect the rel8ns to have ancestor and past. (E: 20cb7723dc33ae1ef808fe76d1bf4b25)`); }\n if (!keystoneIbGib.rel8ns.past || keystoneIbGib.rel8ns.past.length === 0) {\n throw new Error(`(UNEXPECTED) keystoneIbGib.rel8ns.past falsy or empty? we expect the firstGen call to generate an interstitial ibgib that we will splice out. (E: 0fd8388d045ab9f37834c27d67e78825)`);\n }\n\n // reset n\n keystoneIbGib.data.n = 0;\n // reset tjp\n keystoneIbGib.data.isTjp = true;\n delete keystoneIbGib.rel8ns.tjp;\n // reset past\n delete keystoneIbGib.rel8ns.past;\n\n // recalculate gib\n keystoneIbGib.gib = await getGib({ ibGib: keystoneIbGib });\n\n // save and register\n await metaspace.put({ ibGib: keystoneIbGib, space, });\n await metaspace.registerNewIbGib({ ibGib: keystoneIbGib, space, });\n\n return keystoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\nexport async function validateKeystoneGraph({\n keystoneIbGib,\n dependencyGraph,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace,\n space,\n}: {\n keystoneIbGib: KeystoneIbGib_V1,\n /**\n * set this if you already have a reference to the graph. It is the caller's\n * responsibility to enforce {@link getLatest}.\n */\n dependencyGraph?: FlatIbGibGraph,\n /**\n * if true, then this will get the latest keystone known in the incoming\n * {@link keystoneIbGib} timeline, as found in {@link space}.\n */\n getLatest: boolean,\n invalidIfMoreRecentKeystoneFoundInSpace: boolean,\n space: IbGibSpaceAny,\n}): Promise<string[]> {\n const lc = `[${validateKeystoneGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 22e1ca1d5a08a3f90b7fe9da95df7b26)`); }\n\n // maybe too defensive but...\n if (!keystoneIbGib) { throw new Error(`(UNEXPECTED) keystoneIbGib falsy? (E: 26482871d529fff6e8899c5d8a6c3826)`); }\n\n const errors: string[] = [];\n\n // first, get the latest if that is the case...\n if (getLatest) {\n const keystoneAddr = getIbGibAddr({ ibGib: keystoneIbGib });\n const resGetLatestAddrs = await getLatestAddrs({\n ibGibs: [keystoneIbGib],\n space,\n });\n if (!resGetLatestAddrs.data) { throw new Error(`(UNEXPECTED) resGetLatestAddrs.data falsy? (E: 3a23b3b420a8da1928219ca8d47b2126)`); }\n if (!resGetLatestAddrs.data.latestAddrsMap) { throw new Error(`(UNEXPECTED) resGetLatestAddrs.data.latestAddrsMap falsy? (E: 93f1180598fb65a4b8d36e08d6c50426)`); }\n\n const { latestAddrsMap } = resGetLatestAddrs.data;\n if (Object.keys(latestAddrsMap).length === 0) {\n throw new Error(`(UNEXPECTED) latestAddrsMap truthy but empty? (E: 7142f8f7625b9186281d08251e407826)`);\n }\n\n const latestAddr = latestAddrsMap[keystoneAddr];\n if (latestAddr) {\n if (latestAddr !== keystoneAddr) {\n if (invalidIfMoreRecentKeystoneFoundInSpace) {\n errors.push(`${lc} more recent keystone (${latestAddr}) found than the one passed in (${keystoneAddr}) in space (${space.ib}). (E: 64bf48de9448ee5c7528bf03bed2a826)`);\n } else {\n // get the latest ibgib and point the incoming ref to that\n const [latestKeystoneIbGib] = await getIbGibsFromCache_fallbackToSpaces({\n addrs: [latestAddr],\n space,\n });\n keystoneIbGib = latestKeystoneIbGib as KeystoneIbGib_V1;\n }\n } else {\n // the incoming ibgib **is** the latest keystone, so nothing more to be done.\n if (logalot) { console.log(`${lc} incoming keystone (${keystoneAddr}) is the latest in the space (${space.ib}) (I: 8ffbd8d6cbc8a461e5e7f1084bd22a26)`); }\n }\n } else {\n // keystone not found in space?\n console.warn(`${lc} keystoneIbGib (${keystoneAddr}) not found in space (${space.ib}). I don't know what the implications of this are. (W: 258c88742448db34a585669484771826)`)\n }\n }\n\n dependencyGraph ??= await getDependencyGraph({\n ibGib: keystoneIbGib,\n space,\n });\n\n const depIbGibs = Object.values(dependencyGraph);\n const { mapWithTjp_NoDna, mapWithTjp_YesDna, mapWithoutTjps, } =\n splitPerTjpAndOrDna({ ibGibs: depIbGibs });\n\n\n // there should be no DNA\n if (Object.keys(mapWithTjp_YesDna).length > 0) {\n errors.push(`${lc} DNA found. Keystones should NOT have DNA. (E: a3ec7827c4284cdea61c2372c0615826)`);\n }\n\n // is there a tjp? I think there is, so mapWithoutTjps should also be\n // empty\n if (Object.keys(mapWithoutTjps).length > 0) {\n errors.push(`${lc} Non-tjp ibgibs found? Keystones are expected to have tjps. (E: a3ec7827c4284cdea61c2372c0615826)`);\n }\n\n if (Object.keys(mapWithTjp_NoDna).length > 0) {\n // happy path here. These should be the keystone ibgibs. we will put\n // them in order, then do validation on the transitions. We will\n // also check other graph-scoped integrity of keystones (like do\n // certain properties match among ALL keystones, etc.)\n\n const keystoneIbGibs_unordered = Object.values(mapWithTjp_NoDna);\n\n const orderedKeystonesMap = getTimelinesGroupedByTjp({ ibGibs: keystoneIbGibs_unordered });\n const keys = Object.keys(orderedKeystonesMap);\n if (keys.length === 0) {\n throw new Error(`(UNEXPECTED) orderedKeystonesMap empty? (E: d437b80bef58e83a034b28af46278726)`);\n } else if (keys.length > 1) {\n // keys.length > 1\n throw new Error(`(UNEXPECTED) more than one timeline in keystone graph? ATOW (02/19/2026) we are expecting only a single timeline. (E: 66085b14e3887a59c872afd240511f26)`);\n }\n // happy path: exactly one timeline\n const keystoneTjpAddr = keys[0];\n const keystoneIbGibs_ordered = orderedKeystonesMap[keystoneTjpAddr] as KeystoneIbGib_V1[];\n\n if (keystoneIbGibs_ordered.length === 0) { throw new Error(`(UNEXPECTED) empty keystoneIbGibs_ordered? (E: 4a6b085aa8a76828a8d65367e7e56526)`); }\n\n const genesisErrors = await validateGenesisKeystone({\n keystoneIbGib: keystoneIbGibs_ordered[0]\n });\n genesisErrors.forEach(x => errors.push(x));\n\n if (keystoneIbGibs_ordered.length === 1) {\n // only the genesis keystone, which has already been done.\n } else {\n // more than 1 keystone, so validate the transitions\n for (let i = 0; i < keystoneIbGibs_ordered.length - 1; i++) {\n const prevIbGib = keystoneIbGibs_ordered[i];\n const currentIbGib = keystoneIbGibs_ordered[i + 1];\n const transitionErrors = await validateKeystoneTransition({\n prevIbGib, currentIbGib\n });\n if (transitionErrors.length > 0) {\n errors.push(`${lc} keystone has ${transitionErrors.length} transition errors. i: ${i}. prevIbGib addr: ${getIbGibAddr({ ibGib: prevIbGib })}. currentIbGib addr: ${getIbGibAddr({ ibGib: currentIbGib })}. (E: 3ac17be916141d0c286ca5a87bb1b426)`);\n transitionErrors.forEach(x => errors.push(x));\n }\n\n break; // stop after the first found transition error\n }\n }\n } else {\n // one of the other errors regarding mapWithTjp_YesDna or\n // mapWithoutTjps will exist at this point, so we don't need to add\n // any more errors.\n if (errors.length === 0) { throw new Error(`(UNEXPECTED) mapWithTjp_NoDna empty (which is an error) but errors.length === 0? If we get here, we expect one of the other errors to have been populated. (E: 7bca2866b6f8fca318923de8c88e8826)`); }\n }\n\n return errors;\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n}\n\n", "import { DomainInfo } from \"../../../types.mjs\";\r\n\r\nexport interface KeystoneParams {\r\n domainInfo: DomainInfo;\r\n}\r\n\r\n// #region KeystoneGetQueryParams\r\nexport const DEFAULT_QUERY_PARAMS_GET_KEYSTONE = {\r\n /**\r\n * If true, will get the latest keystone frame.\r\n */\r\n getLatest: true,\r\n /**\r\n * If true, will get the keystone's entire dependency graph\r\n */\r\n getGraph: true,\r\n};\r\n/**\r\n * @see {@link DEFAULT_QUERY_PARAMS_GET_KEYSTONE} key/values for jsdocs\r\n */\r\nexport type KeystoneGetQueryParams = Partial<typeof DEFAULT_QUERY_PARAMS_GET_KEYSTONE>;\r\nexport type KNOWN_QUERY_PARAMS_KEYSTONE_GET = keyof KeystoneGetQueryParams;\r\nexport const KNOWN_QUERY_PARAMS_KEYSTONE_GET = Object.keys(DEFAULT_QUERY_PARAMS_GET_KEYSTONE) as KNOWN_QUERY_PARAMS_KEYSTONE_GET[];\r\nexport function isKnownQueryParamsKey_KeystoneGet(key: any): key is KNOWN_QUERY_PARAMS_KEYSTONE_GET {\r\n return !!key && typeof key === 'string' ?\r\n KNOWN_QUERY_PARAMS_KEYSTONE_GET.includes(key as any) :\r\n false;\r\n}\r\n// #endregion KeystoneGetQueryParams\r\n", "/**\n * @module serve-gib/handlers/api/keystone\n */\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';\nimport { validateKeystoneGraph } from '@ibgib/core-gib/dist/keystone/keystone-helpers.mjs';\nimport { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';\nimport { IbGibSpaceResultData, IbGibSpaceResultIbGib, IbGibSpaceResultRel8ns } from '@ibgib/core-gib/dist/witness/space/space-types.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';\nimport { ServeGibHandlerWithMetaspaceBase } from '../../handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../types.mjs';\nimport { API_PATH_REGEXES } from '../../../../path-constants.mjs';\nimport {\n DEFAULT_QUERY_PARAMS_GET_KEYSTONE, isKnownQueryParamsKey_KeystoneGet,\n KeystoneGetQueryParams, KeystoneParams, KNOWN_QUERY_PARAMS_KEYSTONE_GET\n} from './keystone-handler-types.mjs';\nimport { validateAndCoerceBooleanQueryParam } from '../../../serve-gib-helpers.mjs';\n\nexport interface KeystoneGetResponseBody {\n domainGraph: Record<string, KeystoneIbGib_V1>;\n}\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * GET /api/keystone/:domainAddr\n * GET /api/keystone/:domainAddr&getLatest=true\n */\nexport class KeystoneGetHandler extends ServeGibHandlerWithMetaspaceBase<KeystoneParams, KeystoneGetQueryParams> {\n protected override lc: string = `[${KeystoneGetHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'GET';\n protected override regex = API_PATH_REGEXES.KEYSTONE_ADDR;\n\n protected override async parseParamsImpl(reqCtx: RequestContext<KeystoneParams, KeystoneGetQueryParams>): Promise<KeystoneParams | undefined> {\n const lc = `${this.lc}[${this.parseParamsImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n const match = reqCtx.pathname.match(this.regex);\n if (!match) { throw new Error(`(UNEXPECTED) match falsy for regex? at this point, we have passed canHandleRoute, so this should parse correctly. (E: 02c868316604c7c26823380885b79c26)`); }\n\n const domainIb = decodeURIComponent(match[1]);\n const domainGib = decodeURIComponent(match[2]);\n const domainAddr = getIbGibAddr({ ib: domainIb, gib: domainGib });\n return {\n domainInfo: this.getDomainInfo({ domainAddr }),\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected override async validateQueryParams({ queryParams }: { queryParams: any; }): Promise<string[]> {\n const lc = `${this.lc}[${this.validateQueryParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: f619e8121988498cd8e8928986663826)`); }\n\n const errors: string[] = [];\n\n // strict checking\n const queryParamsKeys = Object.keys(queryParams);\n const invalidKeys: string[] = queryParamsKeys.filter(x => !isKnownQueryParamsKey_KeystoneGet(x));\n if (invalidKeys.length > 0) {\n throw new Error(`invalid query params keys: ${invalidKeys.join(', ')}. valid query params keys: ${KNOWN_QUERY_PARAMS_KEYSTONE_GET.join(', ')} (E: f9642823b568a1cfe89e0401567ac826)`);\n }\n\n // Enforce that EVERY key must have a validation function mapping\n type ValidationFn = () => Promise<void>;\n const ValidationFns: Record<KNOWN_QUERY_PARAMS_KEYSTONE_GET, ValidationFn> = {\n getLatest: async () => {\n validateAndCoerceBooleanQueryParam(queryParams, 'getLatest', errors);\n },\n getGraph: async () => {\n validateAndCoerceBooleanQueryParam(queryParams, 'getGraph', errors);\n },\n };\n\n // execute all validation functions\n for (const fn of Object.values(ValidationFns)) {\n await fn();\n }\n\n return errors;\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async handleRouteImpl(reqCtx: RequestContext<KeystoneParams, KeystoneGetQueryParams>): Promise<ResponseResult | undefined> {\n const lc = `[${this.handleRouteImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const { metaspace } = reqCtx;\n if (!metaspace) { throw new Error(`(UNEXPECTED) reqCtx.metaspace falsy? (E: 871a396f7e824989981a1508d0d17826)`); }\n\n const { domainInfo } = reqCtx.params as KeystoneParams;\n if (!domainInfo) { throw new Error(`(UNEXPECTED) reqCtx.params.domainInfo falsy? at this point, we've passed canHandleRoute so this should be truthy (E: 5d3e96d9f8d8f65258d530af0e223826)`); }\n const { addr: domainAddr } = domainInfo;\n\n // if (!domainIb || !domainGib) { return this.error(400, 'Keystone address required'); }\n // const addr = `${domainIb}^${domainGib}`;\n\n if (logalot) { console.log(`${lc} domainAddr: ${domainAddr} (I: ea08786359e85481a89c77d84e8f0826)`); }\n\n // there are two paths for this: getLatest or not (get exact given addr)\n // this should be driven by queryParams\n\n const queryParams = {\n ...DEFAULT_QUERY_PARAMS_GET_KEYSTONE,\n ...(reqCtx.queryParams ?? {}),\n }\n\n const { getLatest, getGraph } = queryParams;\n\n if (!getLatest) { throw new Error(`\"getLatest: false\" not implemented yet. currently this always returns the graph. (E: befd28156438a0b538cf107872e89b26)`); }\n if (!getGraph) { throw new Error(`\"getGraph: false\" not implemented yet. currently this always returns the graph. (E: 84c8a88fdb28e72d884addb8f43fc826)`); }\n\n /**\n * get the default local user space that corresponds to the current\n * keystone domain (which is what the metaspace was initialized\n * with).\n */\n const space = await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(`(UNEXPECTED) space falsy? we couldn't get the default local userspace from the metaspace for the addr (${domainAddr}) (E: 934551f1845f94c8320a8a980025c526)`); }\n\n\n // use this code later if we de\n let domainAddr_latest: IbGibAddr = domainAddr;\n if (getLatest) {\n const latestAddr = await metaspace.getLatestAddr({ addr: domainAddr, space });\n if (latestAddr) { domainAddr_latest = latestAddr; }\n }\n\n\n const domainGraph = await metaspace.getDependencyGraph({\n ibGibAddr: domainAddr_latest,\n /**\n * since domain is a keystone, \"live\" is not needed because the\n * entire graph is composed of stones with no timelines.\n */\n live: false,\n space,\n });\n\n let keystoneIbGib: KeystoneIbGib_V1 = domainGraph[domainAddr_latest] as KeystoneIbGib_V1;\n if (!keystoneIbGib) {\n const errorMsg_addrInfo = domainAddr_latest === domainAddr ?\n `domainAddr: ${domainAddr}` :\n `domainAddr: ${domainAddr}, domainAddr_latest: `\n return this.error(404, `Keystone not found. ${errorMsg_addrInfo} (E: 0238c85f94889607088220a324db1826)`); /* <<<< returns early */\n }\n\n // go ahead and validate even though we just pulled this (should be\n // valid or it shouldn't have been persisted)\n\n const keystoneValidationErrors = await validateKeystoneGraph({\n keystoneIbGib,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace: getLatest,\n space,\n });\n\n if (keystoneValidationErrors.length > 0) {\n const errorMsg_addrInfo = domainAddr_latest === domainAddr ?\n `domainAddr: ${domainAddr}` :\n `domainAddr: ${domainAddr}, domainAddr_latest: `\n\n return this.error(404, `Keystone invalid for ${errorMsg_addrInfo}. validationErrors: ${keystoneValidationErrors.join('|')}`); /* <<<< returns early */\n }\n\n // valid keystone graph\n const responseBody: KeystoneGetResponseBody = {\n domainGraph: domainGraph as Record<string, KeystoneIbGib_V1>,\n };\n return this.ok(responseBody);\n\n } catch (error) {\n const emsg = `${lc} ${extractErrorMsg(error)}`;\n console.error(emsg);\n return this.error(500, emsg);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "/**\n * @module serve-gib/handlers/api/keystone/keystone-genesis.handler\n *\n * POST /api/keystone/genesis\n *\n * Accepts a single genesis-frame keystone ibgib from the client and\n * bootstraps a new domain-isolated metaspace for it.\n *\n * ## request body\n *\n * ```json\n * { \"keystoneIbGib\": <KeystoneIbGib_V1> }\n * ```\n *\n * ## validation steps\n *\n * 1. Body contains `keystoneIbGib` (single ibgib, not an array).\n * 2. Intrinsic hash validation passes (`validateIbGibIntrinsically`).\n * 3. Structural keystone check: `ib` starts with `\"keystone\"`, no `past` in\n * `rel8ns` (genesis = TJP frame, no prior timeline).\n * 4. Domain uniqueness: the path derived from the keystone's tjpGib must not\n * already exist on disk \u2014 if it does, return 409 Conflict.\n * 5. Bootstrap: call `bootstrapDomainMetaspace` to create folders + metaspace.\n * 6. Persist the keystone ibgib into the newly created domain space.\n *\n * ## notes\n *\n * Unlike domain-scoped handlers, this handler does NOT rely on\n * `reqCtx.metaspace` (which is undefined when no domain exists yet). It\n * creates the metaspace itself using `bootstrapDomainMetaspace`.\n */\n\nimport { existsSync } from 'node:fs';\n\nimport { extractErrorMsg, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';\nimport { ServeGibHandlerBase } from '../../handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../../../types.mjs';\nimport { API_PATH_REGEXES } from '../../../../path-constants.mjs';\nimport { getDomainRootPath } from '../../../../bootstrap-helper.mjs';\nimport { bootstrapDomainMetaspace } from '../../../../bootstrap-helper.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || true;\n\n\n\n\n/**\n * POST /api/keystone/genesis\n *\n * No path params \u2014 the domain is derived from the incoming keystone ibgib.\n */\nexport class KeystoneGenesisHandler extends ServeGibHandlerBase<undefined, undefined> {\n protected override lc: string = `[${KeystoneGenesisHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'POST';\n protected override regex = API_PATH_REGEXES.KEYSTONE_GENESIS;\n\n protected async handleRouteImpl(\n reqCtx: RequestContext<undefined, undefined>\n ): Promise<ResponseResult | undefined> {\n const lc = `${this.lc}[${this.handleRouteImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c526)`); }\n\n // ----------------------------------------------------------------\n // 1. Parse body \u2014 expect { keystoneIbGib }\n // ----------------------------------------------------------------\n let parsed: any;\n try {\n parsed = JSON.parse(reqCtx.body);\n } catch {\n return this.error(400, 'Request body must be valid JSON');\n }\n\n const { keystoneIbGib } = parsed;\n if (!keystoneIbGib) {\n return this.error(400, 'Body must contain keystoneIbGib');\n }\n\n // ----------------------------------------------------------------\n // 2. Intrinsic hash validation\n // ----------------------------------------------------------------\n const intrinsicErrors = await validateIbGibIntrinsically({ ibGib: keystoneIbGib });\n if (intrinsicErrors) {\n return this.error(422, 'Intrinsic keystone validation failed', { errors: intrinsicErrors });\n }\n\n // ----------------------------------------------------------------\n // 3. Structural keystone + genesis-frame checks\n // ----------------------------------------------------------------\n const keystoneService = new KeystoneService_V1();\n const keystoneErrors = await keystoneService.validateGenesisKeystone({\n keystoneIbGib\n });\n if (keystoneErrors && keystoneErrors.length > 0) {\n return this.error(422, 'Keystone genesis validation failed', { errors: keystoneErrors });\n }\n\n // ----------------------------------------------------------------\n // 4. Domain uniqueness check \u2014 409 if the domain already exists\n // ----------------------------------------------------------------\n const addr = getIbGibAddr({ ibGib: keystoneIbGib });\n const { tjpGib, punctiliarHash } = getGibInfo({ ibGibAddr: addr });\n const domainGib = tjpGib || punctiliarHash;\n if (!domainGib) {\n return this.error(422, `Could not extract domain identifier from keystone address: ${addr}`);\n }\n\n const domainRootPath = getDomainRootPath(domainGib, reqCtx.dataDir);\n if (existsSync(domainRootPath)) {\n return this.error(409, `Domain already exists for this keystone (tjpGib: ${domainGib}). Use PUT /api/keystone/evolve/:domainAddr to evolve.`);\n }\n\n // ----------------------------------------------------------------\n // 5. Bootstrap the new domain metaspace (creates folders)\n // ----------------------------------------------------------------\n const metaspace = await bootstrapDomainMetaspace(addr, reqCtx.dataDir);\n\n // ----------------------------------------------------------------\n // 6. Persist the genesis keystone into the new domain space\n // ----------------------------------------------------------------\n const space = await metaspace.getLocalUserSpace({ lock: false });\n if (!space) {\n throw new Error(`(UNEXPECTED) Could not get local user space after bootstrapping domain for ${addr} (E: b1c2d3e4f5a6b7c8d9e0f1a2b3c4d526)`);\n }\n\n await metaspace.put({ ibGibs: [keystoneIbGib], space });\n await metaspace.registerNewIbGib({ ibGib: keystoneIbGib, space });\n\n console.log(`${lc} domain created and keystone persisted: ${addr}`);\n if (logalot) { console.log(`${lc} keystoneIbGib: ${pretty(keystoneIbGib)} (I: d598c6ff7a48997d585b84c19c464826)`); }\n return this.ok({ success: true, addr }, 201);\n } catch (error) {\n const emsg = extractErrorMsg(error);\n console.error(`${lc} ${emsg}`);\n return this.error(500, emsg);\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "import { extractErrorMsg, mergeMapsOrArrays_Naive } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';\nimport {\n KeystoneData_V1, KeystoneIbGib_V1, KeystonePoolConfig, KeystoneClaim,\n KeystoneChallengePool, KeystoneReplenishStrategy, KeystoneRevocationInfo,\n} from './keystone-types.mjs';\nimport { KeystoneStrategyFactory } from './strategy/keystone-strategy-factory.mjs';\nimport { POOL_ID_REVOKE, KEYSTONE_VERB_REVOKE, KEYSTONE_VERB_MANAGE, KEYSTONE_CHECKPOINT_FREQUENCY } from './keystone-constants.mjs';\nimport {\n addToBindingMap, createKeystoneIbGibImpl, evolvePersistAndRegisterKeystone,\n generateOpaqueChallengeId, resolveTargetPool, selectChallengeIds,\n solveAndReplenish, validateKeystoneTransition,\n validateGenesisKeystone, validateKeystoneGraph\n} from './keystone-helpers.mjs';\nimport { IbGibSpaceAny } from '../witness/space/space-base-v1.mjs';\nimport { MetaspaceService } from '../witness/space/metaspace/metaspace-types.mjs';\nimport { FlatIbGibGraph } from '../common/other/graph-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\n/**\n * Facade for managing Keystone Identities.\n *\n * Handles Genesis, Authorized Evolution (Signing), and Validation.\n */\nexport class KeystoneService_V1 {\n protected lc: string = `[${KeystoneService_V1.name}]`;\n\n /**\n * Creates a brand new Keystone Identity Timeline.\n */\n async genesis({\n masterSecret,\n frameDetails,\n configs,\n metaspace,\n space,\n }: {\n masterSecret: string;\n frameDetails?: any;\n configs: KeystonePoolConfig[];\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.genesis.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: c98ae8adbc5888dbf84c5aced7610b25)`); }\n\n const challengePools: KeystoneChallengePool[] = [];\n\n for (const config of configs) {\n const strategy = KeystoneStrategyFactory.create({ config });\n const poolSecret = await strategy.derivePoolSecret({ masterSecret });\n const challenges: { [id: string]: any } = {};\n const bindingMap: { [char: string]: string[] } = {};\n\n const targetSize = config.behavior.size;\n const timestamp = Date.now().toString();\n\n for (let i = 0; i < targetSize; i++) {\n const challengeId = await generateOpaqueChallengeId({\n salt: config.salt, timestamp, index: i\n });\n\n const solution = await strategy.generateSolution({\n poolSecret, poolId: config.id, challengeId,\n });\n const challenge = await strategy.generateChallenge({ solution });\n challenges[challengeId] = challenge;\n\n // Populate Binding Map\n addToBindingMap(bindingMap, challengeId);\n }\n\n challengePools.push({\n id: config.id,\n config,\n challenges,\n bindingMap\n });\n }\n\n if (challengePools.length === 0) { throw new Error(`No challenge pools created. (E: 38e538530996940e1f16a8b199995825)`); }\n\n const data: KeystoneData_V1 = { challengePools, proofs: [] };\n if (frameDetails) { data.frameDetails = frameDetails; }\n const keystoneIbGib = await createKeystoneIbGibImpl({ data, metaspace, space });\n return keystoneIbGib;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Signs a claim by solving challenges from a specific pool and evolving the Keystone timeline.\n *\n * Uses a hybrid selection strategy: Mandatory IDs (Alice) + Sequential (FIFO) + Random (Stochastic).\n *\n * Supports Delegation via `poolFilter` to find specific foreign pools.\n *\n * todo: wrap this and other entire keystone sign/method implementations in locks on the keystone's tjpGib.\n */\n async sign({\n latestKeystone,\n masterSecret,\n claim,\n poolId,\n poolFilter,\n requiredChallengeIds = [],\n frameDetails,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n /**\n * The secret used to solve the challenges.\n * If signing with a native pool, this is the User's Master Secret.\n * If signing with a foreign/delegated pool, this is the Delegate's Secret.\n */\n masterSecret: string;\n claim: Partial<KeystoneClaim>;\n /**\n * Explicit ID of the pool to use.\n */\n poolId?: string;\n /**\n * Optional predicate to find a pool.\n * Useful for finding delegates via metadata without knowing the exact ID.\n * e.g. (p) => p.metadata?.delegate === 'Bob'\n */\n poolFilter?: (pool: KeystoneChallengePool) => boolean;\n requiredChallengeIds?: string[];\n frameDetails?: any;\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.sign.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const prevData = latestKeystone.data!;\n\n if (prevData.revocationInfo) { throw new Error(`Keystone has been revoked. Cannot sign. (E: 4f2198c39116d15c48ba191940316825)`); }\n\n // 1. Identify Authority (Resolve Pool)\n const pool = resolveTargetPool({\n pools: prevData.challengePools,\n poolId,\n poolFilter,\n verb: claim.verb\n });\n\n if (logalot) { console.log(`${lc} Selected pool: ${pool.id} (size: ${Object.keys(pool.challenges).length}) (I: 6b26d6f4aad18380f2b3a0989b592826)`); }\n\n // 2. Calculate Costs (Select IDs)\n const idsToSolve = selectChallengeIds({\n pool,\n targetAddr: claim.target,\n requiredChallengeIds\n });\n\n // 3. Pay the Cost (Solve & Replenish)\n // This helper handles the Strategy creation, Secret derivation, Solving,\n // and the calculation of the Next state for ALL pools.\n const { proof, nextPools } = await solveAndReplenish({\n targetPoolId: pool.id,\n prevPools: prevData.challengePools,\n masterSecret,\n challengeIds: idsToSolve,\n claim,\n requiredChallengeIds\n });\n\n // 4. Construct New Data\n const n = (prevData.n ?? 0) + 1;\n let checkpointDetails: any | undefined;\n if (n % KEYSTONE_CHECKPOINT_FREQUENCY === 0) {\n // Generate a temporary view of the keystone as it would be in this frame\n // to calculate the aggregated state.\n const currentFrameView: KeystoneIbGib_V1 = {\n ...latestKeystone,\n data: { ...prevData, frameDetails }\n };\n checkpointDetails = await this.getAggregateDetails({\n latestKeystone: currentFrameView,\n metaspace,\n space\n });\n }\n\n const newData: KeystoneData_V1 = {\n challengePools: nextPools,\n proofs: [proof],\n frameDetails,\n checkpointDetails,\n };\n\n // 5. Commit (Evolve, Persist, Register)\n const resKeystone = await evolvePersistAndRegisterKeystone({\n prevIbGib: latestKeystone,\n newData,\n metaspace,\n space\n });\n\n return resKeystone;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Validates a keystone.\n *\n * ## NOTES\n *\n * Atow (12/22/2025) this only validates the transition from Prev -> Curr.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n *\n * @see {@link validateKeystoneTransition}\n */\n async validate({\n currentIbGib,\n prevIbGib,\n }: {\n currentIbGib: KeystoneIbGib_V1;\n prevIbGib: KeystoneIbGib_V1;\n }): Promise<string[]> {\n // todo: change this to validate the entire keystone graph. the next\n // step is to walk the history and validate each transition.\n const errors = await validateKeystoneTransition({ currentIbGib, prevIbGib });\n return errors;\n }\n\n /**\n * Validates a genesis keystone.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n */\n async validateGenesisKeystone({\n keystoneIbGib,\n }: {\n keystoneIbGib: KeystoneIbGib_V1;\n }): Promise<string[]> {\n return await validateGenesisKeystone({ keystoneIbGib });\n }\n\n /**\n * Retrieves the latest keystone frame for the given address.\n * \n * Uses `metaspace.getLatestAddr` to find the actual tip instead of trusting\n * an incoming payload's `past` rel8n.\n * \n * @see `ibgib-get-pattern` SKILL.md\n */\n async getLatestKeystone({\n addr,\n metaspace,\n space,\n }: {\n addr: string;\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.getLatestKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n \n const latestAddr = await metaspace.getLatestAddr({ tjpAddr: addr, space });\n if (!latestAddr) {\n throw new Error(`could not find latest addr for ${addr}`);\n }\n\n const resGet = await metaspace.get({ addr: latestAddr, space });\n if (resGet.success && resGet.ibGibs && resGet.ibGibs.length > 0) {\n return resGet.ibGibs[0] as KeystoneIbGib_V1;\n } else {\n const resIbGib = resGet.rawResultIbGib as any;\n const addrsNotFound = resIbGib?.data?.addrsNotFound ?? 'unknown';\n throw new Error(`couldn't find latest keystone at ${latestAddr}. addrsNotFound: ${addrsNotFound}? resGet.errorMsg: ${resGet.errorMsg}`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Validates an entire keystone graph from tip to genesis.\n *\n * @returns Array of validation error strings. Empty array means Valid.\n */\n async validateKeystoneGraph({\n keystoneIbGib,\n dependencyGraph,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace,\n space,\n }: {\n keystoneIbGib: KeystoneIbGib_V1,\n /**\n * set this if you already have a reference to the graph. It is the caller's\n * responsibility to enforce {@link getLatest}.\n */\n dependencyGraph?: FlatIbGibGraph,\n /**\n * if true, then this will get the latest keystone known in the incoming\n * {@link keystoneIbGib} timeline, as found in {@link space}.\n */\n getLatest: boolean,\n invalidIfMoreRecentKeystoneFoundInSpace: boolean,\n space: IbGibSpaceAny,\n }): Promise<string[]> {\n const lc = `${this.lc}[${this.validateKeystoneGraph.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 01c5cd455038c270cbf1effc1704af26)`); }\n\n return await validateKeystoneGraph({\n keystoneIbGib,\n dependencyGraph,\n getLatest,\n invalidIfMoreRecentKeystoneFoundInSpace,\n space\n });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Permanently revokes the Identity.\n *\n * Logic:\n * 1. Locates the 'revoke' pool.\n * 2. Solves required challenges to prove ownership.\n * 3. Wipes the pool (via the delete all strategy in solveAndReplenish).\n * 4. Sets the revocationInfo on the new frame.\n */\n async revoke({\n latestKeystone,\n masterSecret,\n reason = \"User initiated revocation\",\n frameDetails,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n masterSecret: string;\n reason?: string;\n frameDetails?: any;\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.revoke.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const prevData = latestKeystone.data!;\n\n // 1. Identify Authority (Resolve Revoke Pool)\n const pool = resolveTargetPool({\n pools: prevData.challengePools,\n poolId: POOL_ID_REVOKE // Explicitly require the special revoke pool\n });\n\n // 2. Construct Claim\n const claim: Partial<KeystoneClaim> = {\n verb: KEYSTONE_VERB_REVOKE,\n target: getIbGibAddr({ ibGib: latestKeystone })\n };\n\n // 3. Calculate Costs\n const idsToSolve = selectChallengeIds({\n pool,\n targetAddr: claim.target,\n requiredChallengeIds: []\n });\n\n if (idsToSolve.length === 0) { throw new Error(`Revocation policy selected 0 challenges? Check config for pool ${pool.id}. Revocation requires proof. (E: 97e5a8356d241ae7b882db791cb1f825)`); }\n\n // 4. Pay the Cost & Scorched Earth\n // The revoke pool config should have 'replenishStrategy:\n // KeystoneReplenishStrategy.deleteAll', causing solveAndReplenish\n // to return an empty pool in nextPools.\n const { proof, nextPools } = await solveAndReplenish({\n targetPoolId: pool.id,\n prevPools: prevData.challengePools,\n masterSecret,\n challengeIds: idsToSolve,\n claim,\n requiredChallengeIds: []\n });\n // warn if nextPools contains pool.id that isn't empty (we were\n // supposed to do \"scorched earth\" which empties the pool)\n if (nextPools.find(p => p.id === pool.id && Object.keys(p.challenges).length > 0)) {\n console.warn(`${lc} revocation pool ${pool.id} is not empty after revocation. Is the revocation pool replenish strategy set to ${KeystoneReplenishStrategy.deleteAll}? (W: 300c28bc8b98fc3e3c0b0d988344f825)`);\n }\n\n // 5. Construct Revocation Info\n const revocationInfo: KeystoneRevocationInfo = { reason, proof };\n\n // 6. Construct New Data\n const n = (prevData.n ?? 0) + 1;\n let checkpointDetails: any | undefined;\n if (n % KEYSTONE_CHECKPOINT_FREQUENCY === 0) {\n const currentFrameView: KeystoneIbGib_V1 = {\n ...latestKeystone,\n data: { ...prevData, frameDetails, revocationInfo }\n };\n checkpointDetails = await this.getAggregateDetails({\n latestKeystone: currentFrameView,\n metaspace,\n space\n });\n }\n\n const newData: KeystoneData_V1 = {\n challengePools: nextPools,\n proofs: [proof],\n revocationInfo,\n frameDetails,\n checkpointDetails,\n };\n\n // 7. Commit\n const newKeystone = await evolvePersistAndRegisterKeystone({\n prevIbGib: latestKeystone,\n newData,\n metaspace,\n space\n });\n\n return newKeystone;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Structural evolution: Adds new challenge pools to the keystone.\n *\n * Use Case: Adding a delegate (Server) for SSO, adding a recovery key,\n * or rotating to a new set of pools.\n *\n * Requires the Master Secret to authorize the change via a pool containing\n * the 'manage' verb.\n */\n async addPools({\n latestKeystone,\n masterSecret,\n newPools,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n /**\n * Alice's Master Secret.\n * Required to solve challenges from the Admin/Manage pool to authorize this change.\n */\n masterSecret: string;\n /**\n * The pools to add.\n * NOTE: These are fully constructed Pool objects.\n * If they are foreign (Bob's), Alice must have constructed them\n * using Bob's challenges + Her config restrictions + isForeign=true.\n */\n newPools: KeystoneChallengePool[];\n metaspace: MetaspaceService;\n space: IbGibSpaceAny;\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.addPools.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!latestKeystone.data) { throw new Error(`(UNEXPECTED) latestKeystone.data falsy? (E: 7334c8faed128166a999d428c7805b25)`); }\n const prevData = latestKeystone.data;\n\n if (prevData.revocationInfo) { throw new Error(`Keystone has been revoked. Cannot add pools. (E: 8599f8f51c78d722252ddb2894fdbe25)`); }\n\n if (newPools.length === 0) { throw new Error(`No new pools provided to add. (E: 6599f8f51c78d722252ddb2894fdbe25)`); }\n\n // 1. Identify Authority (Resolve Admin Pool)\n // We need a pool that allows the 'manage' verb.\n const adminPool = resolveTargetPool({\n pools: prevData.challengePools,\n verb: KEYSTONE_VERB_MANAGE,\n });\n\n if (logalot) { console.log(`${lc} Authorized via pool: ${adminPool.id}`); }\n\n // 2. Construct the Management Claim\n const target = getIbGibAddr({ ibGib: latestKeystone });\n const claim: Partial<KeystoneClaim> = {\n verb: KEYSTONE_VERB_MANAGE,\n target, // I am managing myself\n // Scope creates a cryptographic commitment to WHICH pools are being added\n scope: JSON.stringify({ add: newPools.map(p => p.id) })\n };\n\n // 3. Calculate Costs\n const idsToSolve = selectChallengeIds({\n pool: adminPool,\n targetAddr: target\n });\n\n // 4. Pay the Cost (Solve & Replenish)\n // This authorizes the change by evolving the admin pool.\n const { proof, nextPools: replenishedExistingPools } = await solveAndReplenish({\n targetPoolId: adminPool.id,\n prevPools: prevData.challengePools,\n masterSecret,\n challengeIds: idsToSolve,\n claim,\n });\n\n // 5. Mutate Structure (Add the new pools)\n // We verify ID uniqueness cheaply here to prevent blatant errors\n const existingIds = new Set(replenishedExistingPools.map(p => p.id));\n for (const newPool of newPools) {\n if (existingIds.has(newPool.id)) {\n throw new Error(`Cannot add pool. ID collision: ${newPool.id} (E: 8a4c2b1d3e5f6a7b8c9d0e1f2a3b4c5d)`);\n }\n }\n\n const finalPools = [...replenishedExistingPools, ...newPools];\n\n // 6. Construct New Data\n const n = (prevData.n ?? 0) + 1;\n let checkpointDetails: any | undefined;\n if (n % KEYSTONE_CHECKPOINT_FREQUENCY === 0) {\n const currentFrameView: KeystoneIbGib_V1 = {\n ...latestKeystone,\n data: { ...prevData, challengePools: finalPools }\n };\n checkpointDetails = await this.getAggregateDetails({\n latestKeystone: currentFrameView,\n metaspace,\n space\n });\n }\n\n const newData: KeystoneData_V1 = {\n challengePools: finalPools,\n proofs: [proof], // The proof authorizes the structure change\n checkpointDetails,\n };\n\n // 7. Commit\n const newKeystone = await evolvePersistAndRegisterKeystone({\n prevIbGib: latestKeystone,\n newData,\n metaspace,\n space\n });\n\n return newKeystone;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n /**\n * Consolidates the state of a Keystone identity across its history.\n * Walks back until it hits a checkpoint or genesis.\n */\n async getAggregateDetails({\n latestKeystone,\n metaspace,\n space,\n }: {\n latestKeystone: KeystoneIbGib_V1;\n metaspace: MetaspaceService;\n space?: IbGibSpaceAny;\n }): Promise<any> {\n const lc = `${this.lc}[${this.getAggregateDetails.name}]`;\n try {\n let aggregated: any = {};\n let current = latestKeystone;\n\n while (current) {\n const data = current.data!;\n\n // 1. If we hit a checkpoint, merge it and STOP.\n if (data.checkpointDetails) {\n aggregated = mergeMapsOrArrays_Naive({\n dominant: aggregated,\n recessive: data.checkpointDetails\n });\n break;\n }\n\n // 2. Merge this frame's details\n if (data.frameDetails) {\n aggregated = mergeMapsOrArrays_Naive({\n dominant: aggregated,\n recessive: data.frameDetails\n });\n }\n\n // 3. Genesis check (n=0)\n if (data.n === 0) { break; }\n\n // 4. Walk back\n const past = current.rel8ns?.past;\n const prevAddr = (past && past.length > 0) ? past[past.length - 1] : undefined;\n if (!prevAddr) { break; }\n\n const res = await metaspace.get({ addr: prevAddr, space });\n if (!res.success || !res.ibGibs || res.ibGibs.length === 0) {\n throw new Error(`Could not find previous keystone frame at ${prevAddr} (E: e3d069b22e11e550e58844889ddb5325)`);\n }\n current = res.ibGibs[0] as KeystoneIbGib_V1;\n }\n\n return aggregated;\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n }\n}\n", "/**\n * @module serve-gib/handlers/api/keystone/keystone-evolve.handler\n *\n * PUT /api/keystone/evolve/:domainAddr\n *\n * Receives an evolved domain keystone (`I^I1.Itjp`) and any related\n * ibgibs (e.g., the `S^Stjp` session keystone).\n *\n * Validates the evolution, verifies the `S` session keystone, and persists\n * them to the domain metaspace to authorize the sync session.\n */\n\nimport { extractErrorMsg, pretty } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { getIbGibAddr } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { validateIbGibIntrinsically } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { getGibInfo } from '@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';\nimport { ServeGibHandlerWithMetaspaceBase } from '../../handler-base.mjs';\nimport { API_PATH_REGEXES } from '../../../../path-constants.mjs';\nimport { DomainInfo, ParamsWithDomain, RequestContext, ResponseResult } from '../../../types.mjs';\nimport { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';\nimport { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';\nimport { IbGibSpaceAny } from '@ibgib/core-gib/dist/witness/space/space-base-v1.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || true;\n\ninterface EvolveParams extends ParamsWithDomain {\n domainAddr: string;\n}\n\ninterface EvolveBody {\n keystoneIbGib: KeystoneIbGib_V1;\n relatedIbGibs?: IbGib_V1[];\n}\n\nexport class KeystoneEvolveHandler extends ServeGibHandlerWithMetaspaceBase<EvolveParams, EvolveBody> {\n protected override lc: string = `[${KeystoneEvolveHandler.name}]`;\n protected override method: 'PUT' = 'PUT';\n protected override regex = API_PATH_REGEXES.KEYSTONE_EVOLVE;\n\n protected override async parseParamsImpl(reqCtx: RequestContext<EvolveParams, any>): Promise<EvolveParams | undefined> {\n const match = reqCtx.pathname.match(this.regex);\n if (match && match.length >= 3) {\n const domainIb = decodeURIComponent(match[1]);\n const domainGib = decodeURIComponent(match[2]);\n const domainAddr = getIbGibAddr({ ib: domainIb, gib: domainGib });\n return {\n domainAddr,\n domainInfo: this.getDomainInfo({ domainAddr })\n };\n }\n return undefined;\n }\n\n protected override async validateQueryParams({ queryParams }: { queryParams: any; }): Promise<string[]> {\n return []; // We don't expect any query parameters for evolution\n }\n\n protected override async handleRouteImpl(reqCtx: RequestContext<EvolveParams>): Promise<ResponseResult> {\n const lc = `${this.lc}[handleRouteImpl]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n if (!reqCtx.params) { return this.error(400, 'Invalid parameters'); }\n if (!reqCtx.metaspace) { return this.error(500, 'Metaspace not initialized'); }\n\n const { domainAddr } = reqCtx.params;\n const bodyStr = reqCtx.body;\n if (!bodyStr) { return this.error(400, 'Empty body'); }\n\n let parsed: EvolveBody;\n try {\n parsed = JSON.parse(bodyStr);\n } catch (err) {\n return this.error(400, 'Invalid request JSON body: bodyStr does NOT parse. (E: 2f81c8c80a6884ff32b877671e92f326)');\n }\n\n const { keystoneIbGib, relatedIbGibs = [] } = parsed;\n if (!keystoneIbGib) {\n return this.error(400, 'Invalid request. Body must contain keystoneIbGib (E: e234647f79282982c8012fe8015f5826)');\n }\n\n const addr = getIbGibAddr({ ibGib: keystoneIbGib });\n\n // 1. Intrinsic hash validation\n const intrinsicErrors = await validateIbGibIntrinsically({ ibGib: keystoneIbGib });\n if (intrinsicErrors && intrinsicErrors.length > 0) {\n return this.error(422, 'Intrinsic keystone validation failed. (E: 6efeb756cb0fb6c3187c8448c5035826)', { errors: intrinsicErrors });\n }\n\n // 2. Verify URL :domainAddr matches the keystone's tjp\n const { tjpGib } = getGibInfo({ ibGibAddr: addr });\n const expectedTjpGib = getGibInfo({ ibGibAddr: domainAddr }).punctiliarHash;\n if (tjpGib !== expectedTjpGib) {\n return this.error(422, `Keystone tjpGib (${tjpGib}) does not match URL domainAddr tjpGib (${expectedTjpGib}) (E: 703d3c64b7382f21f863c1e83533c826)`);\n }\n\n // 3. Load previous frame (the current tip in metaspace)\n const space = await reqCtx.metaspace.getLocalUserSpace({ lock: false });\n if (!space) {\n return this.error(500, 'No local user space found (E: a1144e5d6cd9641fb82d6b359f131126)');\n }\n const keystoneService = new KeystoneService_V1();\n let prevIbGib: KeystoneIbGib_V1;\n try {\n prevIbGib = await keystoneService.getLatestKeystone({\n addr: domainAddr,\n metaspace: reqCtx.metaspace,\n space\n });\n } catch (error) {\n return this.error(422, `Could not retrieve previous keystone tip for ${domainAddr} (E: bc2da8fb4dbda2c65851de9dd0b0eb26)`, { error: extractErrorMsg(error) });\n }\n\n // 4. Validate Evolution Transition\n const validationErrors = await keystoneService.validate({\n currentIbGib: keystoneIbGib,\n prevIbGib\n });\n if (validationErrors && validationErrors.length > 0) {\n return this.error(422, 'Keystone evolution validation failed', { errors: validationErrors });\n }\n\n // 5. Check Single Pool Restriction\n const restrictionError = this.validateSinglePoolRestriction(keystoneIbGib);\n if (restrictionError) {\n return this.error(422, restrictionError); /* <<<< returns early */\n }\n\n // 6. Route by claim verb\n const proofs = keystoneIbGib.data?.proofs ?? [];\n if (proofs.length !== 1) { throw new Error(`(UNEXPECTED) evolving keystone with proofs.length !== 1? we just checked that the length of proofs was exactly 1 in checkSinglePoolRestriction (E: 3021bb0ce9783e27c8e3492820aeb926)`); }\n const { claim } = proofs[0];\n if (!claim) { throw new Error(`proof.claim is falsy (E: e1dd983db341185528a75768919ea826)`); }\n const { verb } = claim;\n if (!verb) { throw new Error(`(UNEXPECTED) claim.verb falsy? atow (05/15/2026) I thought all claims should have a verb. I could be wrong of course as it's still early days. (E: 933a9856d6625b547d7ec158d678a826)`); }\n\n switch (verb) {\n case 'sync':\n return await this.handleSyncEvolution(reqCtx, keystoneIbGib, relatedIbGibs, space);\n default:\n throw new Error(`non-sync keystone evolution not yet implemented (E: 83cb29bf67d681542bfd486d0f91e726)`);\n // return await this.handleDefaultEvolution(reqCtx, keystoneIbGib, space);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n return this.error(500, `Internal error evolving keystone`, { details: extractErrorMsg(error) });\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected validateSinglePoolRestriction(keystoneIbGib: KeystoneIbGib_V1): string | undefined {\n const proofs = keystoneIbGib.data?.proofs ?? [];\n if (proofs.length === 0) {\n return 'No proofs found in evolved keystone data';\n }\n\n const poolIds = new Set<string>();\n for (const proof of proofs) {\n for (const solution of proof.solutions || []) {\n if (solution.poolId) {\n poolIds.add(solution.poolId);\n }\n }\n }\n\n if (poolIds.size > 1) {\n return `Multiple pools evolved (${Array.from(poolIds).join(', ')}). Only one pool evolution allowed at a time.`;\n }\n\n return undefined; // no error\n }\n\n protected async handleSyncEvolution(\n reqCtx: RequestContext<EvolveParams>,\n keystoneIbGib: KeystoneIbGib_V1,\n relatedIbGibs: IbGib_V1[],\n space: IbGibSpaceAny\n ): Promise<ResponseResult> {\n const lc = `${this.lc}[${this.handleSyncEvolution.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 80cf7ba10a781fad87171b747de10826)`); }\n\n if (logalot) { console.log(`${lc} starting...`); }\n\n const proofs = keystoneIbGib.data?.proofs ?? [];\n if (proofs.length !== 1) { throw new Error(`(UNEXPECTED) proofs.length !== 1? (E: ac9748a187f87455bc01fdeeb4363826)`); }\n const claim = proofs[0].claim;\n const sAddr = claim?.target;\n if (!sAddr) {\n return this.error(422, 'No target address found in sync claim');\n }\n\n // Validate S^Stjp (session keystone ibgib) from relatedIbGibs\n const sIbGib = relatedIbGibs.find(ibGib => getIbGibAddr({ ibGib }) === sAddr) as KeystoneIbGib_V1 | undefined;\n if (!sIbGib) {\n return this.error(422, `Session keystone ${sAddr} must be provided in relatedIbGibs`);\n }\n\n const sIntrinsicErrors = await validateIbGibIntrinsically({ ibGib: sIbGib });\n if (sIntrinsicErrors && sIntrinsicErrors.length > 0) {\n return this.error(422, 'Intrinsic validation failed for S^Stjp', { errors: sIntrinsicErrors });\n }\n\n const keystoneService = new KeystoneService_V1();\n const sGenesisErrors = await keystoneService.validateGenesisKeystone({ keystoneIbGib: sIbGib });\n if (sGenesisErrors && sGenesisErrors.length > 0) {\n return this.error(422, 'Genesis validation failed for S^Stjp', { errors: sGenesisErrors });\n }\n\n // Persist both I and S\n await reqCtx.metaspace!.put({ ibGibs: [keystoneIbGib, sIbGib], space });\n await reqCtx.metaspace!.registerNewIbGib({ ibGib: keystoneIbGib, space });\n await reqCtx.metaspace!.registerNewIbGib({ ibGib: sIbGib, space });\n\n const addr = getIbGibAddr({ ibGib: keystoneIbGib });\n if (logalot) { console.log(`${lc} domain evolution stored and registered: ${addr}`); }\n\n return this.ok({\n message: `Successfully evolved domain keystone with session keystone`,\n });\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async handleDefaultEvolution(\n reqCtx: RequestContext<EvolveParams>,\n keystoneIbGib: KeystoneIbGib_V1,\n space: IbGibSpaceAny\n ): Promise<ResponseResult> {\n const lc = `${this.lc}[${this.handleDefaultEvolution.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 8b755b4087b16c0d760d3ca397fad726)`); }\n\n // Persist only I\n await reqCtx.metaspace!.put({ ibGibs: [keystoneIbGib], space });\n await reqCtx.metaspace!.registerNewIbGib({ ibGib: keystoneIbGib, space });\n\n const addr = getIbGibAddr({ ibGib: keystoneIbGib });\n if (logalot) { console.log(`${lc} domain evolution stored and registered: ${addr} (I: 990d686a19d645afaa624e386caac826)`); }\n\n return this.ok({\n message: `Successfully evolved domain keystone. (I: 4cd058a08a171069982a7f3808cbe826)`,\n });\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n}\n", "/**\n * @module serve-gib/handlers/static-handler\n *\n * Handler for serving static client assets and SPA fallback.\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { existsSync, statSync } from 'node:fs';\nimport { join, extname } from 'node:path';\n\nimport { ServeGibHandlerBase } from './handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../types.mjs';\nimport { isValidStaticPath } from '../../path-helper.mjs';\nimport { GLOBAL_LOG_A_LOT } from '../constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport class StaticFileHandler extends ServeGibHandlerBase {\n protected override lc: string = `[${StaticFileHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'GET';\n protected override regex = /.*/;\n\n private MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'text/javascript; charset=utf-8',\n '.mjs': 'text/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n '.webp': 'image/webp',\n };\n\n constructor(private clientDir: string) { super(); }\n\n protected async handleRouteImpl(reqCtx: RequestContext): Promise<ResponseResult | undefined> {\n const lc = `${this.lc}[${this.handleRouteImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n // Hardened path validation\n const { pathname } = reqCtx;\n if (!isValidStaticPath(pathname)) { return undefined; }\n\n let filePath = join(this.clientDir, pathname);\n\n // Directory \u2192 index.html\n if (existsSync(filePath) && statSync(filePath).isDirectory()) {\n filePath = join(filePath, 'index.html');\n }\n\n // File not found \u2192 SPA fallback\n if (!existsSync(filePath)) {\n filePath = join(this.clientDir, 'index.html');\n }\n\n // Final check just in case the fallback doesn't exist\n if (!existsSync(filePath)) { return undefined; }\n\n const content = await readFile(filePath);\n const ext = extname(filePath).toLowerCase();\n const contentType = this.MIME_TYPES[ext] ?? 'application/octet-stream';\n\n return {\n status: 200,\n headers: { 'Content-Type': contentType },\n body: content\n };\n } catch (error: any) {\n console.error(`${lc} ${error.message}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "/**\n * @module serve-gib/handlers/error-handler\n *\n * Default error handler for serve-gib.\n */\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../constants.mjs';\nimport { ServeGibHandlerBase } from './handler-base.mjs';\nimport { RequestContext, ResponseResult, ServeGibHttpMethod } from '../types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nexport class ErrorHandler extends ServeGibHandlerBase {\n protected override lc: string = `[${ErrorHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'ALL';\n protected override regex = /.*/;\n\n async handleRouteImpl(reqCtx: RequestContext): Promise<ResponseResult | undefined> {\n const lc = `${this.lc}[${this.handleRouteImpl.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting...`); }\n\n const { rawUrl, pathname, method, } = reqCtx;\n\n // This is the fallback handler\n return this.error(404, 'Not Found', { method, rawUrl, pathname });\n } catch (error: any) {\n console.log(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n}\n", "import { createHash } from 'node:crypto';\nimport { IncomingMessage } from 'node:http';\nimport { Socket } from 'node:net';\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nconst WS_MAGIC = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';\n\n/** Encodes a UTF-8 string as a minimal unmasked WebSocket text frame. */\nexport function encodeTextFrame(text: string): Buffer {\n const payload = Buffer.from(text, 'utf-8');\n const payloadLen = payload.length;\n\n let header: Buffer;\n if (payloadLen < 126) {\n header = Buffer.alloc(2);\n header[0] = 0x81; // FIN + opcode 1 (text)\n header[1] = payloadLen;\n } else if (payloadLen < 65536) {\n header = Buffer.alloc(4);\n header[0] = 0x81;\n header[1] = 126;\n header.writeUInt16BE(payloadLen, 2);\n } else {\n header = Buffer.alloc(10);\n header[0] = 0x81;\n header[1] = 127;\n header.writeBigUInt64BE(BigInt(payloadLen), 2);\n }\n\n return Buffer.concat([header, payload]);\n}\n\n/** Decodes a masked client WebSocket text frame. Returns null for non-text or incomplete frames. */\nexport function decodeTextFrame(data: Buffer): string | null {\n try {\n if (data.length < 2) { return null; }\n\n const opcode = data[0] & 0x0f;\n if (opcode === 0x8) { return null; } // Close\n if (opcode !== 0x1) { return null; } // Text only\n\n const masked = (data[1] & 0x80) !== 0;\n let payloadStart = 2;\n let payloadLen = data[1] & 0x7f;\n\n if (payloadLen === 126) {\n payloadLen = data.readUInt16BE(2);\n payloadStart = 4;\n } else if (payloadLen === 127) {\n payloadLen = Number(data.readBigUInt64BE(2));\n payloadStart = 10;\n }\n\n if (masked) {\n const maskStart = payloadStart;\n payloadStart += 4;\n const mask = data.slice(maskStart, maskStart + 4);\n const payload = data.slice(payloadStart, payloadStart + payloadLen);\n for (let i = 0; i < payload.length; i++) {\n payload[i] ^= mask[i % 4];\n }\n return payload.toString('utf-8');\n }\n\n return data.slice(payloadStart, payloadStart + payloadLen).toString('utf-8');\n } catch (error) {\n console.error(`[ws-helper] decode error: ${extractErrorMsg(error)}`);\n return null;\n }\n}\n\n/** Encodes a WebSocket close frame (opcode 0x8) with optional status code. */\nexport function encodeCloseFrame(code = 1000): Buffer {\n const frame = Buffer.alloc(4);\n frame[0] = 0x88;\n frame[1] = 2;\n frame.writeUInt16BE(code, 2);\n return frame;\n}\n\n/** Performs the RFC 6455 opening handshake. */\nexport function performHandshake(req: IncomingMessage, socket: Socket): boolean {\n try {\n const key = req.headers['sec-websocket-key'];\n if (!key) {\n socket.write('HTTP/1.1 400 Bad Request\\r\\n\\r\\nMissing Sec-WebSocket-Key');\n socket.destroy();\n return false;\n }\n\n const acceptKey = createHash('sha1')\n .update(key + WS_MAGIC)\n .digest('base64');\n\n const response = [\n 'HTTP/1.1 101 Switching Protocols',\n 'Upgrade: websocket',\n 'Connection: Upgrade',\n `Sec-WebSocket-Accept: ${acceptKey}`,\n '\\r\\n',\n ].join('\\r\\n');\n\n socket.write(response);\n return true;\n } catch (error) {\n console.error(`[ws-helper] handshake error: ${extractErrorMsg(error)}`);\n socket.destroy();\n return false;\n }\n}\n", "/**\n * @module handlers/api/debug/ws-echo.handler\n *\n * Minimal WebSocket echo handler for validating end-to-end WebSocket\n * plumbing: Traefik passthrough \u2192 Node.js upgrade event \u2192 browser client.\n *\n * ## intent\n *\n * This is a diagnostic-only endpoint. The goal is to confirm that:\n * 1. Traefik correctly forwards WS upgrade requests to the container\n * 2. The Node.js `upgrade` event fires and we can accept the handshake\n * 3. The browser client can open a wss:// connection and exchange frames\n *\n * Once WS sync is confirmed end-to-end, this handler can be removed or\n * gated behind an env flag.\n *\n * ## endpoint\n *\n * `GET /api/debug/ws-echo` (with Upgrade: websocket header)\n *\n * On connect: server sends `{\"status\":\"connected\",\"msg\":\"ws-echo ready\"}`\n * On message: server echoes `{\"echo\":<original message>}`\n * On close: server logs and cleans up\n */\n\nimport { IncomingMessage } from 'node:http';\nimport { Socket } from 'node:net';\n\nimport { extractErrorMsg } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../../constants.mjs';\nimport {\n encodeTextFrame, decodeTextFrame, encodeCloseFrame, performHandshake\n} from '../../ws/ws-helper.mjs';\nimport { API_PATH_REGEXES } from '../../../../path-constants.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT;\n\nconst lc = `[WsEchoHandler]`;\n\n\n// ---------------------------------------------------------------------------\n// Public handler\n// ---------------------------------------------------------------------------\n\n/**\n * Returns true if this request is a WebSocket upgrade to the debug echo path.\n * Call this from the server's `upgrade` event listener.\n */\nexport function canHandleWsUpgrade(req: IncomingMessage): boolean {\n const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;\n return API_PATH_REGEXES.DEBUG_WS_ECHO.test(pathname);\n}\n\n/**\n * Accepts the WebSocket upgrade and sets up the echo loop.\n *\n * Client will receive a JSON `{status:\"connected\"}` on open, and\n * `{echo:<msg>}` for every message it sends.\n */\nexport function handleWsEchoUpgrade(req: IncomingMessage, socket: Socket, head: Buffer): void {\n const lc_fn = `${lc}[handleWsEchoUpgrade]`;\n try {\n if (logalot) { console.log(`${lc_fn} starting...`); }\n\n const ok = performHandshake(req, socket);\n if (!ok) { return; }\n\n // Send the \"connected\" greeting\n socket.write(encodeTextFrame(JSON.stringify({ status: 'connected', msg: 'ws-echo ready' })));\n\n // Echo loop\n socket.on('data', (data: Buffer) => {\n try {\n const text = decodeTextFrame(data);\n if (text === null) {\n // Close frame or unsupported opcode \u2014 send close and end\n socket.write(encodeCloseFrame(1000));\n socket.end();\n return;\n }\n if (logalot) { console.log(`${lc_fn} echo: ${text}`); }\n socket.write(encodeTextFrame(JSON.stringify({ echo: text })));\n } catch (error) {\n console.error(`${lc_fn} error in data handler: ${extractErrorMsg(error)}`);\n socket.destroy();\n }\n });\n\n socket.on('error', (error) => {\n console.error(`${lc_fn} socket error: ${extractErrorMsg(error)}`);\n });\n\n socket.on('close', () => {\n if (logalot) { console.log(`${lc_fn} socket closed.`); }\n });\n\n } catch (error) {\n console.error(`${lc_fn} ${extractErrorMsg(error)}`);\n socket.destroy();\n } finally {\n if (logalot) { console.log(`${lc_fn} complete.`); }\n }\n}\n", "/**\n * @module common/keystone-policies\n *\n * Centralized identity and security policies for the space-gib application.\n * Defines standard configurations for both persistent (Domain) and ephemeral (Session) keystones.\n *\n * ## important\n *\n * This file is part of the `src/common` layer. It MUST NEVER import from\n * `src/client` or `src/server`.\n */\n\nimport { HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport {\n KeystoneReplenishStrategy,\n KeystoneChallengeType,\n KeystoneIbGib_V1,\n KeystoneSolution\n} from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';\nimport { KeystoneStrategyFactory } from '@ibgib/core-gib/dist/keystone/strategy/keystone-strategy-factory.mjs';\n\n// ---------------------------------------------------------------------------\n// 1. Session Keystone (S) Policies\n// ---------------------------------------------------------------------------\n\n/**\n * Default configurations for short-lived session keystones (S^Stjp).\n * These values match the real-world usage in the space-gib client.\n */\nexport const SESSION_KEYSTONE_POLICY = {\n /**\n * Shared parameters across all session pools\n */\n COMMON: {\n ALGO: HashAlgorithm.sha_256,\n TYPE: KeystoneChallengeType.hash_reveal_v1,\n ROUNDS: 2,\n REPLENISH: KeystoneReplenishStrategy.topUp,\n },\n\n /**\n * The primary authorization pool for sync actions (e.g. putting/getting ibgibs).\n */\n DEFAULT_POOL: {\n ID: 'default',\n SIZE: 20,\n SELECT_SEQUENTIALLY: 2,\n SELECT_RANDOMLY: 2,\n /**\n * We want more for this, with future implementations we will not have\n * resource exhaustion.\n */\n TARGET_BINDING_CHARS: 3,\n },\n\n /**\n * Dedicated pool for the WebSocket sync protocol handshake.\n */\n HANDSHAKE_POOL: {\n ID: 'handshake',\n VERB: 'handshake',\n SIZE: 10,\n SELECT_SEQUENTIALLY: 2,\n SELECT_RANDOMLY: 2,\n TARGET_BINDING_CHARS: 0,\n /** Number of IDs the server should demand during the handshake. */\n SERVER_DEMAND_COUNT: 3,\n }\n} as const;\n\n\n// ---------------------------------------------------------------------------\n// 2. Domain/Identity Keystone (I) Policies\n// ---------------------------------------------------------------------------\n\n/**\n * Server-side minimum requirements for long-lived primary identity keystones.\n *\n * [Nag] These are initial placeholder standards and should be reviewed for\n * production hardening.\n */\nexport const DOMAIN_KEYSTONE_SECURITY_STANDARDS = {\n MIN_DEFAULT_POOL_SIZE: 50,\n ALLOWED_ALGORITHMS: [\n HashAlgorithm.sha_256,\n HashAlgorithm.sha_512\n ],\n} as const;\n\n\n// ---------------------------------------------------------------------------\n// 3. Upfront Picket-Fence Handshake Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the lexicographically first challenge from the session keystone's\n * 'handshake' pool to be used as a deterministic, dynamic upfront pre-filter challenge.\n */\nexport function getHandshakeChallenge(keystone: KeystoneIbGib_V1): { challengeId: string; challenge: any } {\n const handshakePool = (keystone.data?.challengePools ?? []).find(\n (p) => p.id === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID\n );\n if (!handshakePool) {\n throw new Error(`Keystone missing \"${SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID}\" pool`);\n }\n\n const challengeIds = Object.keys(handshakePool.challenges).sort();\n if (challengeIds.length === 0) {\n throw new Error(`Handshake pool has no challenges`);\n }\n\n const challengeId = challengeIds[0];\n const challenge = handshakePool.challenges[challengeId];\n return { challengeId, challenge };\n}\n\n/**\n * Cryptographically validates the upfront picket-fence solution against the session keystone.\n * Verifies that the client solved the lexicographically first challenge from the 'handshake' pool.\n */\nexport async function checkHandshakeSolution(\n keystone: KeystoneIbGib_V1,\n solutionValue: string\n): Promise<boolean> {\n const handshakePool = (keystone.data?.challengePools ?? []).find(\n (p) => p.id === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID\n );\n if (!handshakePool) {\n return false;\n }\n\n const { challengeId, challenge } = getHandshakeChallenge(keystone);\n const strategy = KeystoneStrategyFactory.create({ config: handshakePool.config });\n const solution: KeystoneSolution = {\n type: 'hash-reveal-v1',\n challengeId,\n poolId: SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID,\n value: solutionValue\n };\n\n return await strategy.validateSolution({ solution, challenge });\n}\n\n// this is what we had by default inside the sync saga coordinator\n// const primaryPoolConfig: KeystonePoolConfig_HashV1 = {\n// allowedVerbs: [KEYSTONE_VERB_MANAGE],\n// id: SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID,\n// salt: sagaId,\n// behavior: {\n// size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE, // Large pool for many signatures\n// replenish: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY,\n// selectSequentially: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL,\n// selectRandomly: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM,\n// targetBindingChars: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING,\n// },\n// type: KeystoneChallengeType.hash_reveal_v1,\n// algo: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,\n// rounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,\n// };", "/**\n * @module handlers/ws/sync-upgrade.handler\n *\n * Handles WebSocket upgrades for the sync protocol.\n * Implements a challenge/response handshake using Keystone identity.\n */\n\nimport { IncomingMessage } from 'node:http';\nimport { Socket } from 'node:net';\n\nimport { extractErrorMsg, getUUID } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';\nimport { IbGibAddr } from '@ibgib/ts-gib/dist/types.mjs';\nimport { getIbGibAddr, getIbAndGib } from '@ibgib/ts-gib/dist/helper.mjs';\nimport { validateIbGibAddr } from '@ibgib/ts-gib/dist/V1/validate-helper.mjs';\nimport { KeystoneService_V1 } from '@ibgib/core-gib/dist/keystone/keystone-service-v1.mjs';\nimport { KeystoneIbGib_V1 } from '@ibgib/core-gib/dist/keystone/keystone-types.mjs';\nimport { parseKeystoneIb } from '@ibgib/core-gib/dist/keystone/keystone-helpers.mjs';\nimport { IbGib_V1 } from '@ibgib/ts-gib/dist/V1/types.mjs';\nimport { IbGibSpaceResultIbGib, IbGibSpaceResultData, IbGibSpaceResultRel8ns } from '@ibgib/core-gib/dist/witness/space/space-types.mjs';\n\nimport { GLOBAL_LOG_A_LOT } from '../../constants.mjs';\nimport {\n encodeTextFrame, decodeTextFrame, encodeCloseFrame, performHandshake\n} from './ws-helper.mjs';\nimport { API_PATH_REGEXES } from '../../../path-constants.mjs';\nimport { ServeGibHandlerWithMetaspaceBase } from '../handler-base.mjs';\nimport { ParamsWithDomain, RequestContext, ResponseResult, ServeGibHttpMethod } from '../../types.mjs';\nimport { SESSION_KEYSTONE_POLICY, checkHandshakeSolution } from '../../../../common/keystone-policies.mjs';\nimport { AuthChallengeMessage, AuthFailMessage, AuthInitMessage, AuthOkMessage, AuthProofMessage, HandshakeMessage } from './ws-types.mjs';\n\nconst logalot = GLOBAL_LOG_A_LOT || true;\n\n/**\n * Handles WebSocket upgrades for sync by validating against Keystone identity.\n *\n * Reuses ServeGibHandlerWithMetaspaceBase to ensure consistent metaspace\n * initialization from the request context.\n */\nexport interface SyncUpgradeQueryParams {\n sAddr: string;\n solution: string;\n}\n\nexport interface SyncUpgradeRequestContext extends RequestContext<ParamsWithDomain, SyncUpgradeQueryParams> {\n sAddr_tjp?: IbGibAddr;\n demandedIds?: string[];\n}\n\nexport class SyncUpgradeHandler extends ServeGibHandlerWithMetaspaceBase<ParamsWithDomain, SyncUpgradeQueryParams> {\n protected override lc: string = `[${SyncUpgradeHandler.name}]`;\n protected override method: ServeGibHttpMethod = 'GET';\n protected override regex = API_PATH_REGEXES.SYNC_WS;\n\n /**\n * Entry point for WebSocket upgrades.\n * Orchestrates the upgrade, handshake, and keystone authorization.\n * @returns true if the upgrade was handled (even if it failed auth), false if path mismatch.\n */\n async handleUpgrade(reqCtx: RequestContext<ParamsWithDomain>, socket: Socket, head: Buffer): Promise<boolean> {\n const lc_fn = `${this.lc}[handleUpgrade]`;\n try {\n if (logalot) { console.log(`${lc_fn} starting... (I: d772c676239f1f0a823c14a8063d4826)`); }\n\n // 1. Initial validation\n if (!this.canHandleRoute(reqCtx)) {\n if (logalot) { console.log(`${lc_fn} path/method mismatch. (I: 234198c0f649dfdf0e2d21f86b3ff826)`); }\n return false;\n }\n\n const ctx = reqCtx as SyncUpgradeRequestContext;\n\n // Populate params (e.g. domain info) from the request context\n ctx.params = await this.parseParams(ctx);\n ctx.queryParams = await this.parseQueryParams(ctx);\n\n // 2. Initialize Metaspace Context (bootstrapDomainMetaspace)\n await this.initConcreteContext(ctx);\n\n // 2b. Perform upfront picket-fence pre-filter validation\n await this.validateUpfrontHandshake(ctx);\n\n // 3. RFC 6455 Handshake\n const ok = performHandshake(ctx as any as IncomingMessage, socket);\n if (!ok) { return true; }\n\n // 4. Setup Auth Challenge\n const challengeUuid = await getUUID();\n\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-challenge-init',\n challengeUuid\n })));\n\n socket.on('data', async (data: Buffer) => {\n await this.handleUpgrade_socketDataHandler({\n reqCtx: ctx,\n challengeUuid,\n socket,\n data,\n })\n });\n\n return true;\n } catch (error) {\n console.error(`${lc_fn} fatal: ${extractErrorMsg(error)}`);\n socket.destroy();\n return true;\n }\n }\n\n protected async handleUpgrade_socketDataHandler({\n reqCtx,\n challengeUuid,\n socket,\n data,\n }: {\n reqCtx: SyncUpgradeRequestContext,\n challengeUuid: string,\n socket: Socket,\n data: Buffer,\n }): Promise<any> {\n const lc = `[${this.handleUpgrade_socketDataHandler.name}]`;\n if (logalot) { console.log(`${lc} starting... (I: 3ba9a857899f0479030e323b755fe826)`); }\n try {\n debugger; //\n const text = decodeTextFrame(data);\n if (text === null) {\n socket.write(encodeCloseFrame());\n socket.end();\n return; /* <<<< returns early */\n }\n\n const msg = JSON.parse(text) as HandshakeMessage;\n switch (msg.type) {\n case 'auth-init':\n await this.handleUpgrade_socketDataHandler_authInit({\n reqCtx,\n challengeUuid,\n socket,\n msg,\n })\n break;\n\n\n case 'auth-proof':\n await this.handleUpgrade_socketDataHandler_authProof({\n reqCtx,\n challengeUuid,\n socket,\n msg,\n });\n break;\n\n default:\n if (logalot) { console.log(`${lc} unexpected message type: ${msg.type}`); }\n throw new Error(`unknown msg.type ${msg.type} (E: 8143084554d848f48801fcd5dc5fc826)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: extractErrorMsg(error)\n } as AuthFailMessage)));\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async handleUpgrade_socketDataHandler_authInit({\n reqCtx,\n challengeUuid,\n socket,\n msg,\n }: {\n reqCtx: SyncUpgradeRequestContext,\n challengeUuid: string,\n socket: Socket,\n msg: AuthInitMessage,\n }): Promise<any> {\n const lc = `${this.lc}[${this.handleUpgrade_socketDataHandler_authInit.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 9ef8c8b892f82c7f98e34168f89c4826)`); }\n\n const { sAddr } = msg;\n if (logalot) { console.log(`${lc} auth-init for ${sAddr}`); }\n\n // Load authorized S frame from context's metaspace\n const metaspace = reqCtx.metaspace!;\n const space = await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(\"No space.\"); }\n\n let authorizedS: KeystoneIbGib_V1;\n try {\n authorizedS = await this.getSessionKeystone({ metaspace, space, sAddr });\n if (logalot) { console.log(`${lc} loaded authorizedS:`, JSON.stringify(authorizedS).slice(0, 200) + '...'); }\n } catch (error) {\n console.warn(`${lc} session keystone not found: ${extractErrorMsg(error)}`);\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: 'Session keystone not found on server. Did you complete Step 4?'\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n\n // Identify handshake pool and select demanded IDs\n const handshakePool = (authorizedS.data?.challengePools ?? []).find(p => p.id === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID);\n if (!handshakePool) {\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: `Session keystone missing \"${SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.ID}\" pool`\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n\n const challengeIds = Object.keys(handshakePool.challenges);\n const demandedIds = challengeIds.sort(() => 0.5 - Math.random()).slice(0, SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.SERVER_DEMAND_COUNT);\n reqCtx.demandedIds = demandedIds;\n\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-challenge',\n challengeUuid,\n demandedIds\n } as AuthChallengeMessage)));\n\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n\n /**\n * At this point, the session keystone (S^Stjp) according to the server only\n * has the first frame (tjp) persisted. But the client has successfully\n * initiated the handshake, so it provided the one manual challenge.\n *\n * We (the server) then sent the client some challenge ids and said to the\n * client \"Hey, solve the keystone with these challenges included.\"\n *\n * So now, the client has sent the next evolution of the session keystone,\n * S^S1.Stjp, with those challenge ids included.\n */\n protected async handleUpgrade_socketDataHandler_authProof({\n reqCtx,\n challengeUuid,\n socket,\n msg,\n }: {\n reqCtx: SyncUpgradeRequestContext,\n challengeUuid: string,\n socket: Socket,\n msg: AuthProofMessage,\n }): Promise<any> {\n const lc = `${this.lc}[${this.handleUpgrade_socketDataHandler_authProof.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: b0c185793602f4e4d862785e906cdd26)`); }\n const { proofFrame } = msg;\n if (logalot) { console.log(`${lc} verifying auth-proof...`); }\n\n const sAddr_proofFrame = getIbGibAddr({ ibGib: proofFrame });\n\n // need to get the tip of session keystone\n const metaspace = reqCtx.metaspace!;\n const space = await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(`(UNEXPECTED) no default local user space? (E: 1443da451007921b2da9d2c8b15a4826)`); }\n const sAddr_tjp = reqCtx.sAddr_tjp;\n if (!sAddr_tjp) {\n throw new Error(\"Missing upfront verified session keystone TJP address (E: cb1998fa7c4a11f5ee87b001a4e126a1)\");\n }\n /**\n * this is the latest/tip addr for session keystone that the server\n * is currently aware of.\n *\n * NOTE: We do NOT (!!!) trust the incoming session keystone to\n * drive what the client thinks it the latest addr. Not only is this\n * in the control of a would-be attacker, the client could just be\n * out of date with a race condition.\n */\n const sAddr_latest = await metaspace.getLatestAddr({ tjpAddr: sAddr_tjp, space });\n if (!sAddr_latest) {\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: 'Authorized session keystone tip not found'\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n const sKeystone_latest = await this.getSessionKeystone({\n sAddr: sAddr_latest,\n metaspace,\n space,\n });\n\n const keystoneService = new KeystoneService_V1();\n const validationErrors = await keystoneService.validate({\n prevIbGib: sKeystone_latest,\n currentIbGib: proofFrame,\n });\n\n if (validationErrors && validationErrors.length > 0) {\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: 'Proof validation failed',\n errors: validationErrors\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n\n const proofs = proofFrame.data.proofs ?? [];\n const proof = proofs.find(p => p.claim?.verb === SESSION_KEYSTONE_POLICY.HANDSHAKE_POOL.VERB);\n if (!proof || proof.claim?.target !== challengeUuid) {\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: 'Proof target mismatch or missing handshake claim'\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n\n // Ensure that all of our demanded challenge ids are present in the proof solutions\n const demandedIds = reqCtx.demandedIds;\n if (!demandedIds || demandedIds.length === 0) {\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: 'Server missing active handshake challenge state'\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n\n const solvedIds = new Set(proof.solutions?.map(s => s.challengeId) ?? []);\n const missingIds = demandedIds.filter(id => !solvedIds.has(id));\n if (missingIds.length > 0) {\n socket.write(encodeTextFrame(JSON.stringify({\n type: 'auth-fail',\n message: `Proof is missing demanded solutions: ${missingIds.join(', ')}`\n } as AuthFailMessage)));\n return; /* <<<< returns early */\n }\n\n // Persist the newly validated evolved session keystone tip to the server space\n await metaspace.put({ ibGibs: [proofFrame], space });\n\n if (logalot) { console.log(`${lc} auth successful for ${sAddr_proofFrame} (I: 6d02c649f55c81cfe8f11988f44bca26)`); }\n socket.write(encodeTextFrame(JSON.stringify({ type: 'auth-ok' } as AuthOkMessage)));\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async getSessionKeystone({\n metaspace,\n space,\n sAddr,\n }: {\n metaspace: NonNullable<RequestContext['metaspace']>,\n space: any,\n sAddr: string,\n }): Promise<KeystoneIbGib_V1> {\n const lc = `${this.lc}[${this.getSessionKeystone.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: cb9af0e14d3345bfbc0be35728de7c26)`); }\n\n const resGet = await metaspace.get({ addrs: [sAddr], space });\n\n // Validate result\n if (resGet.success && resGet.ibGibs && resGet.ibGibs.length === 1) {\n return resGet.ibGibs[0] as KeystoneIbGib_V1;\n } else {\n // Robust error handling using rawResultIbGib\n const resIbGib = resGet.rawResultIbGib as IbGibSpaceResultIbGib<IbGib_V1, IbGibSpaceResultData, IbGibSpaceResultRel8ns>;\n const addrsNotFound = resIbGib?.data?.addrsNotFound ?? 'unknown';\n throw new Error(`couldn't find all addrs. addrsNotFound: ${addrsNotFound}? resGet.errorMsg: ${resGet.errorMsg}. space.ib: ${space.ib} (E: f3c87e2b19794358a9e701cd59b8eb26)`);\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected async validateUpfrontHandshake(reqCtx: SyncUpgradeRequestContext): Promise<void> {\n const lc = `${this.lc}[${this.validateUpfrontHandshake.name}]`;\n const sAddr = reqCtx.queryParams?.sAddr;\n const solution = reqCtx.queryParams?.solution;\n\n if (!sAddr || !solution) {\n throw new Error(`Missing upfront handshake parameters (sAddr, solution) (E: 8a4c9a724ddf59998199ec87a9ee126)`);\n }\n\n const metaspace = reqCtx.metaspace!;\n const space = await metaspace.getLocalUserSpace({ lock: false });\n if (!space) { throw new Error(\"No space.\"); }\n\n const authorizedS = await this.getSessionKeystone({ metaspace, space, sAddr });\n const isValid = await checkHandshakeSolution(authorizedS, solution);\n if (!isValid) {\n throw new Error(`Upfront handshake solution verification failed (E: 804c98a724ddf59998199ec87a9ee127)`);\n }\n\n // Store secure TJP address of the verified session keystone in reqCtx\n const past = authorizedS.rel8ns?.past;\n const tjpAddr = (past && past.length > 0) ? past[0] : getIbGibAddr({ ibGib: authorizedS });\n reqCtx.sAddr_tjp = tjpAddr;\n\n if (logalot) { console.log(`${lc} Upfront picket-fence verification succeeded for ${sAddr}!`); }\n }\n\n protected override async parseParamsImpl(reqCtx: RequestContext<ParamsWithDomain>): Promise<ParamsWithDomain | undefined> {\n const lc = `${this.lc}[${this.parseParamsImpl.name}]`;\n try {\n const match = reqCtx.pathname.match(this.regex);\n if (!match) return undefined;\n const domainIb = decodeURIComponent(match[1]);\n const domainGib = decodeURIComponent(match[2]);\n const domainAddr = getIbGibAddr({ ib: domainIb, gib: domainGib });\n\n return {\n domainInfo: this.getDomainInfo({ domainAddr })\n };\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n }\n }\n\n protected override async parseQueryParams(\n reqCtx: RequestContext<ParamsWithDomain, SyncUpgradeQueryParams>\n ): Promise<SyncUpgradeQueryParams | undefined> {\n const lc = `${this.lc}[${this.parseQueryParams.name}]`;\n try {\n if (logalot) { console.log(`${lc} starting... (I: 3ed5ba8d47af31f538fbdb484cfdb826)`); }\n\n const sAddrRaw = reqCtx.url.searchParams.get('sAddr');\n const sAddr = sAddrRaw ? decodeURIComponent(sAddrRaw) : undefined;\n const solution = reqCtx.url.searchParams.get('solution') ?? undefined;\n\n const queryParams: Partial<SyncUpgradeQueryParams> = {};\n if (sAddr !== undefined) { queryParams.sAddr = sAddr; }\n if (solution !== undefined) { queryParams.solution = solution; }\n\n if (Object.keys(queryParams).length > 0) {\n const validationErrors = await this.validateQueryParams({ queryParams });\n if (validationErrors.length === 0) {\n return queryParams as SyncUpgradeQueryParams;\n } else {\n throw new Error(`invalid query params. validationErrors: ${validationErrors.join(', ')} (E: 9355f8a9643803f52f2241f1c7f39826)`);\n }\n } else {\n return undefined;\n }\n } catch (error) {\n console.error(`${lc} ${extractErrorMsg(error)}`);\n throw error;\n } finally {\n if (logalot) { console.log(`${lc} complete.`); }\n }\n }\n\n protected override async validateQueryParams({ queryParams }: { queryParams: any }): Promise<string[]> {\n const errors: string[] = [];\n if (!queryParams) {\n return [\"Missing query parameters: sAddr, solution\"];\n }\n\n if (!queryParams.sAddr) {\n errors.push(\"Missing sAddr\");\n } else {\n try {\n const decodedSAddr = queryParams.sAddr;\n\n // use validateIbGibAddr to ensure that it's a valid address.\n const addrErrors = validateIbGibAddr({ addr: decodedSAddr }) ?? [];\n if (addrErrors.length > 0) {\n errors.push(`Invalid sAddr: ${addrErrors.join(', ')}`);\n } else {\n // get the ib and ensure that it is a keystone ib using parseKeystoneIb (will throw if invalid)\n const { ib } = getIbAndGib({ ibGibAddr: decodedSAddr });\n parseKeystoneIb({ ib });\n }\n } catch (error) {\n errors.push(`Invalid sAddr: ${extractErrorMsg(error)}`);\n }\n }\n\n if (!queryParams.solution) {\n errors.push(\"Missing solution\");\n }\n return errors;\n }\n\n protected override async handleRouteImpl(reqCtx: RequestContext<ParamsWithDomain>): Promise<ResponseResult | undefined> {\n return this.error(400, 'WS endpoint requires upgrade');\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["join", "lc", "logalot", "lc", "logalot", "lc", "lc", "crypto", "subtle", "subtle", "salt", "lc", "hasTjp", "isPrimitive", "lc", "join", "existsSync", "mkdirSync", "writeFile", "rm", "readFile", "readdir", "pathUtils", "Rel8n", "lc", "lc", "hasTjp", "lc", "hasTjp", "lc", "logalot", "lc", "isPrimitive", "logalot", "lc", "constantIbGib", "GLOBAL_LOG_A_LOT", "IB_MAX_LENGTH_DEFAULT", "IB_REGEXP_DEFAULT", "HashAlgorithm", "lc", "lc", "hash", "lc", "hash", "lc", "hash", "lc", "HashAlgorithm", "lc", "HashAlgorithm", "lc", "hash", "lc", "getAlphabetsThisBlock", "hash", "lc", "HashAlgorithm", "result", "lc", "HashAlgorithm", "result", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "logalot", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "logalot", "lc2", "lc", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "IB_REGEXP_DEFAULT", "constantIbGib", "lc", "lc", "logalot", "hasTjp", "lc", "logalot", "toDto", "lc", "logalot", "space", "GLOBAL_LOG_A_LOT", "pathUtils", "logalot", "GLOBAL_LOG_A_LOT", "lc", "toDto", "logalot", "GLOBAL_LOG_A_LOT", "lc", "ibGib", "gottenAddrs", "lc", "logalot", "i", "logalot", "GLOBAL_LOG_A_LOT", "lc", "lc", "logalot", "lc", "lc", "logalot", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "pathUtils", "toDto", "ib", "lc2", "logalot", "GLOBAL_LOG_A_LOT", "lc", "pathUtils", "existsSync", "readFile", "mkdirSync", "writeFile", "toDto", "ib", "rm", "readdir", "GLOBAL_LOG_A_LOT", "GLOBAL_TIMER_NAME", "lc", "logalot", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "toDto", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "lc", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "error", "logalot", "GLOBAL_LOG_A_LOT", "lc", "lc", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "logalot", "GLOBAL_LOG_A_LOT", "lc", "bootstrapIbGib", "error", "hasTjp", "logalot", "GLOBAL_LOG_A_LOT", "lc", "GLOBAL_TIMER_NAME", "logalot", "GLOBAL_LOG_A_LOT", "join", "lc", "logalot", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "logalot", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "lc", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "existsSync", "logalot", "GLOBAL_LOG_A_LOT", "lc", "logalot", "lc", "existsSync", "logalot", "lc", "readFile", "existsSync", "join", "logalot", "lc", "join", "existsSync", "readFile", "logalot", "lc", "logalot", "logalot", "lc", "join", "lc"]
|
|
7
|
+
}
|