@note3/utils 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/applog-collection.d.ts +49 -0
- package/dist/applog-collection.d.ts.map +1 -0
- package/dist/applog-collection.min.js +2 -0
- package/dist/applog-collection.min.js.map +1 -0
- package/dist/chunk-4ARVEMAY.min.js +2 -0
- package/dist/chunk-4ARVEMAY.min.js.map +1 -0
- package/dist/chunk-5TTMWYXD.min.js +3 -0
- package/dist/chunk-5TTMWYXD.min.js.map +1 -0
- package/dist/chunk-IFY2JCCQ.min.js +2 -0
- package/dist/chunk-IFY2JCCQ.min.js.map +1 -0
- package/dist/chunk-KFV32MHC.min.js +2 -0
- package/dist/chunk-KFV32MHC.min.js.map +1 -0
- package/dist/chunk-KHOUPFOL.min.js +1 -0
- package/dist/chunk-KHOUPFOL.min.js.map +1 -0
- package/dist/chunk-KY36PVHK.min.js +2 -0
- package/dist/chunk-KY36PVHK.min.js.map +1 -0
- package/dist/chunk-LDNVHZO7.min.js +2 -0
- package/dist/chunk-LDNVHZO7.min.js.map +1 -0
- package/dist/chunk-MXMMU6NF.min.js +2 -0
- package/dist/chunk-MXMMU6NF.min.js.map +1 -0
- package/dist/chunk-O72M27NE.min.js +2 -0
- package/dist/chunk-O72M27NE.min.js.map +1 -0
- package/dist/chunk-POX3PUJK.min.js +2 -0
- package/dist/chunk-POX3PUJK.min.js.map +1 -0
- package/dist/chunk-XL6QVLYO.min.js +2 -0
- package/dist/chunk-XL6QVLYO.min.js.map +1 -0
- package/dist/chunk-YXZYW2WJ.min.js +78 -0
- package/dist/chunk-YXZYW2WJ.min.js.map +1 -0
- package/dist/chunk-ZJUZ7RVG.min.js +2 -0
- package/dist/chunk-ZJUZ7RVG.min.js.map +1 -0
- package/dist/corejs.d.ts +19 -0
- package/dist/corejs.d.ts.map +1 -0
- package/dist/corejs.min.js +2 -0
- package/dist/corejs.min.js.map +1 -0
- package/dist/helpers.d.ts +7 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.min.js +2 -0
- package/dist/helpers.min.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.min.js +2 -0
- package/dist/index.min.js.map +1 -0
- package/dist/map.d.ts +5 -0
- package/dist/map.d.ts.map +1 -0
- package/dist/map.min.js +2 -0
- package/dist/map.min.js.map +1 -0
- package/dist/note3-regex-constants.d.ts +21 -0
- package/dist/note3-regex-constants.d.ts.map +1 -0
- package/dist/note3-regex-constants.min.js +2 -0
- package/dist/note3-regex-constants.min.js.map +1 -0
- package/dist/note3-utils-nodeps.d.ts +22 -0
- package/dist/note3-utils-nodeps.d.ts.map +1 -0
- package/dist/note3-utils-nodeps.min.js +2 -0
- package/dist/note3-utils-nodeps.min.js.map +1 -0
- package/dist/queries.d.ts +53 -0
- package/dist/queries.d.ts.map +1 -0
- package/dist/queries.min.js +2 -0
- package/dist/queries.min.js.map +1 -0
- package/dist/relation-ordering.d.ts +13 -0
- package/dist/relation-ordering.d.ts.map +1 -0
- package/dist/relation-ordering.min.js +2 -0
- package/dist/relation-ordering.min.js.map +1 -0
- package/dist/tree-builder.d.ts +117 -0
- package/dist/tree-builder.d.ts.map +1 -0
- package/dist/tree-builder.min.js +2 -0
- package/dist/tree-builder.min.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.min.js +2 -0
- package/dist/types.min.js.map +1 -0
- package/dist/url-parsing.d.ts +138 -0
- package/dist/url-parsing.d.ts.map +1 -0
- package/dist/url-parsing.min.js +2 -0
- package/dist/url-parsing.min.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Applog, EntityID } from '@wovin/core/applog';
|
|
2
|
+
import type { ThreadOnlyCurrentNoDeleted } from '@wovin/core/thread';
|
|
3
|
+
/**
|
|
4
|
+
* Generic recursive traversal utility for note tree structures.
|
|
5
|
+
*
|
|
6
|
+
* Traverses a note and all its descendants, applying a mapping function to each
|
|
7
|
+
* node and combining results using a join function.
|
|
8
|
+
*
|
|
9
|
+
* @param thread - Pre-filtered thread (from `lastWriteWins(withoutDeleted(raw))`)
|
|
10
|
+
* @param blockID - The root block ID to start traversal from
|
|
11
|
+
* @param mapKid - Function to apply to each block/relation pair
|
|
12
|
+
* @param joinResults - Function to combine parent result with children results
|
|
13
|
+
* @returns The combined result of the traversal
|
|
14
|
+
*
|
|
15
|
+
* @throws Error if circular references are detected or depth exceeds 42 levels
|
|
16
|
+
*
|
|
17
|
+
* @internal Used by collectSubtreeApplogs; not typically used directly
|
|
18
|
+
*/
|
|
19
|
+
export declare function mapAndRecurseKids<R = void>(thread: ThreadOnlyCurrentNoDeleted, blockID: EntityID, mapKid: (kid: {
|
|
20
|
+
relID: EntityID | null;
|
|
21
|
+
blockID: EntityID;
|
|
22
|
+
}) => R, joinResults: (blockResult: R, kidResults: R[]) => R): any;
|
|
23
|
+
/**
|
|
24
|
+
* Collects all applogs for a note and its entire subtree (descendants).
|
|
25
|
+
*
|
|
26
|
+
* This is a non-reactive utility version for use in non-UI contexts (CLI, scripts, MCP server).
|
|
27
|
+
* It returns a flat array of all applogs found during tree traversal.
|
|
28
|
+
*
|
|
29
|
+
* **Important**: The thread parameter MUST be pre-filtered using `lastWriteWins(withoutDeleted(thread))`
|
|
30
|
+
* to ensure correct tree traversal. Unfiltered threads may:
|
|
31
|
+
* - Include deleted blocks/relations (incorrect tree structure)
|
|
32
|
+
* - Include multiple versions of the same applog (redundant)
|
|
33
|
+
*
|
|
34
|
+
* @param thread - Pre-filtered thread (must be result of `lastWriteWins(withoutDeleted(raw))`)
|
|
35
|
+
* @param blockID - The root block ID to collect from
|
|
36
|
+
* @returns Flat array of all applogs from the block and its descendants
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* import { collectSubtreeApplogs } from '@note3/utils'
|
|
41
|
+
* import { lastWriteWins, withoutDeleted } from '@wovin/core'
|
|
42
|
+
*
|
|
43
|
+
* const filteredThread = withoutDeleted(lastWriteWins(rawThread))
|
|
44
|
+
* const applogs = collectSubtreeApplogs(filteredThread, blockID)
|
|
45
|
+
* console.log(`Collected ${applogs.length} applogs`)
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function collectSubtreeApplogs(thread: ThreadOnlyCurrentNoDeleted, blockID: EntityID): Applog[];
|
|
49
|
+
//# sourceMappingURL=applog-collection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"applog-collection.d.ts","sourceRoot":"","sources":["../src/applog-collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAA;AAGpE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,IAAI,EACzC,MAAM,EAAE,0BAA0B,EAClC,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,CAAC,GAAG,EAAE;IAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,KAAK,CAAC,EACjE,WAAW,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,CAAC,OA0BnD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,0BAA0B,EAClC,OAAO,EAAE,QAAQ,GACf,MAAM,EAAE,CAoBV"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as o}from"./chunk-5TTMWYXD.min.js";var{VERBOSE:g}=o.setup(o.DEBUG);function i(t){let n={};if(!t||t==="")return n;let r=(t.startsWith("#")?t.slice(1):t).split("&");for(let s of r){let[a,h=null]=s.split("=");a!=null&&(n[decodeURIComponent(a)]=h===null?null:decodeURIComponent(h))}return n}function w(t,n){let e=i(t.hash);return e[n]!=null?decodeURIComponent(e[n]):null}function c(t){let n=Object.entries(t).map(([e,r])=>r!=null?`${e}=${encodeURIComponent(r)}`:`${e}`);return n.length>0?`#${n.join("&")}`:""}function R(t,n,e){let r=i(t.hash);r[n]=e,t.hash=c(r)}function U(t,n){let e=i(t.hash);delete e[n],t.hash=c(e)}function $(t,n){let e=i(t.hash);return n in e}var l=["https://note3.app","https://dev.note3.app"];function u(){let t=[...l];if(typeof window<"u"){let n=window.location.pathname;!n.startsWith("/ipfs")&&!n.startsWith("/ipns")&&t.push(window.location.origin)}return t}var p=/\/share\/([a-zA-Z0-9]+)/;function f(t){try{return new URL(t.trim())}catch{return null}}function L(t){let n=f(t);if(!n)return null;let e={};if(n.protocol==="note3:"){let r=n.pathname.match(p);r&&(e.share=r[1])}else if(n.hash&&u().includes(n.origin)){let r=n.hash.match(/^#\/block\/([a-z0-9]+)/);r&&(e.focus=r[1]);let s=m(n.hash);s?.get("share")?e.share=s?.get("share")??void 0:s?.get("pub")?e.share=s?.get("pub")??void 0:s?.get("preview")&&(e.share=s?.get("preview")??void 0,e.preview=!0)}else return null;return g("Parsed Note3 url:",t,e),e}function P({pub:t,block:n,previewPub:e=!1,relative:r=!1}){if(!t&&!n)throw new Error("Neither pub nor block - what kind of URL would that be?");let s=typeof window<"u"?`${window.location.origin}${window.location.pathname}`:"",a=r?"":`${s}#`;return e?`${a}/${n?`block/${n}`:""}${t?`?preview=${t}`:""}`:`${a}/${n?`block/${n}`:""}${t?`?share=${t}`:""}`}function m(t){let e=(t??(typeof window<"u"?window.location.hash:"")).split("?",2);return e.length>=2?new URLSearchParams(e[1]):null}function x(t,n){let e=typeof t.query=="string"?new URLSearchParams(t.query):new URLSearchParams(t.query??{});return Object.entries(n).forEach(([r,s])=>{s?e.set(r,s):e.delete(r)}),`${t.pathname||""}${e.size>0?`?${e.toString()}`:""}`}function N(t,n){let{pathname:e,search:r,hash:s}={...t,...n};return`${e||""}${r||""}${s||""}`}export{i as a,w as b,c,R as d,U as e,$ as f,l as g,u as h,f as i,L as j,P as k,m as l,x as m,N as n};
|
|
2
|
+
//# sourceMappingURL=chunk-4ARVEMAY.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/url-parsing.ts"],"sourcesContent":["import { Logger } from 'besonders-logger'\n\nconst { VERBOSE } = Logger.setup(Logger.DEBUG) // eslint-disable-line unused-imports/no-unused-vars\n\n// ============================================================================\n// Hash Fragment Parsing\n// ============================================================================\n\ninterface HashFragments {\n [key: string]: string | null\n}\n\n/**\n * Parse hash fragments from a URL hash string\n *\n * @param hash The hash string (with or without leading #)\n * @returns An object with key-value pairs from the hash fragments\n */\nexport function parseHashFragments(hash: string): HashFragments {\n const fragments: HashFragments = {}\n\n if (!hash || hash === '') {\n return fragments\n }\n\n // remove the leading # if present\n const hashString = hash.startsWith('#') ? hash.slice(1) : hash\n\n // split by & and parse each fragment\n const pairs = hashString.split('&')\n for (const pair of pairs) {\n const [key, value = null] = pair.split('=')\n if (key != null) {\n fragments[decodeURIComponent(key)] = value === null ? null : decodeURIComponent(value)\n }\n }\n\n return fragments\n}\n\n/**\n * Get a specific hash fragment value from a URL\n *\n * @param url The URL object\n * @param key The fragment key to retrieve\n * @returns The value of the hash fragment, or null if not found\n */\nexport function getHashFragment(url: URL, key: string): string | null {\n const fragments = parseHashFragments(url.hash)\n if (fragments[key] != null) {\n return decodeURIComponent(fragments[key])\n }\n\n return null\n}\n\n/**\n * Convert a hash fragment object to a string\n *\n * @param fragments The hash fragments object\n * @returns Hash string ready to be set as url.hash\n */\nexport function hashFragmentsToString(fragments: HashFragments): string {\n const pairs = Object.entries(fragments).map(([k, v]) => {\n if (v != null) {\n return `${k}=${encodeURIComponent(v)}`\n }\n\n return `${k}`\n })\n return pairs.length > 0 ? `#${pairs.join('&')}` : ''\n}\n\n/**\n * Set a hash fragment on a URL. Modifies the URL in place.\n *\n * @param url The URL to modify\n * @param key The fragment key\n * @param value The fragment value (null to include key without value)\n */\nexport function setHashFragment(url: URL, key: string, value: string | null): void {\n const fragments = parseHashFragments(url.hash)\n fragments[key] = value\n\n url.hash = hashFragmentsToString(fragments)\n}\n\n/**\n * Delete a hash fragment from a URL. Modifies the URL in place.\n *\n * @param url The URL to modify\n * @param key The fragment key to remove\n */\nexport function deleteHashFragment(url: URL, key: string): void {\n const fragments = parseHashFragments(url.hash)\n delete fragments[key]\n\n url.hash = hashFragmentsToString(fragments)\n}\n\n/**\n * Check if a hash fragment exists in a URL\n *\n * @param url The URL to check\n * @param key The fragment key\n * @returns true if the hash fragment exists\n */\nexport function hasHashFragment(url: URL, key: string): boolean {\n const fragments = parseHashFragments(url.hash)\n return key in fragments\n}\n\n// ============================================================================\n// Note3-Specific URL Parsing\n// ============================================================================\n\n/** Canonical Note3 origins */\nexport const CANONICAL_NOTE3_ORIGINS = [\n 'https://note3.app',\n 'https://dev.note3.app',\n] as const\n\n/**\n * Get all known Note3 origins, including current browser origin if applicable\n *\n * Includes current origin when NOT on a path-based IPFS/IPNS gateway\n * (i.e., when pathname doesn't start with /ipfs or /ipns)\n *\n * @returns Array of origins that should be treated as Note3 URLs\n */\nexport function getKnownNote3Origins(): string[] {\n const origins: string[] = [...CANONICAL_NOTE3_ORIGINS]\n\n // Add current origin if running in browser and NOT on a path-based gateway\n if (typeof window !== 'undefined') {\n const pathname = window.location.pathname\n // Include origin when pathname doesn't start with /ipfs or /ipns\n if (!pathname.startsWith('/ipfs') && !pathname.startsWith('/ipns')) {\n origins.push(window.location.origin)\n }\n }\n\n return origins\n}\n\n/** Regex pattern for Note3 protocol URLs */\nconst RE_NOTE3_URL_PATH = /\\/share\\/([a-zA-Z0-9]+)/\n\n/**\n * Safe wrapper for URL constructor. Returns null instead of throwing.\n *\n * @param value The URL string to parse\n * @returns Parsed URL object, or null if parsing fails\n */\nexport function tryParseURL(value: string): URL | null {\n try {\n return new URL(value.trim())\n } catch (error) {\n return null\n }\n}\n\ninterface Note3URLParts {\n share?: string\n preview?: boolean\n focus?: string\n}\n\n/**\n * Parse a Note3 URL in either note3:// protocol or hash-based format\n *\n * Supports formats:\n * - note3://share/{pubkey}\n * - https://note3.app#/block/{id}?share={pubkey}\n * - https://note3.app#/block/{id}?preview={pubkey}\n *\n * @param value The URL string to parse\n * @returns Object with share, preview, and focus properties, or null if not a valid Note3 URL\n */\nexport function tryParseNote3URL(value: string): Note3URLParts | null {\n const url = tryParseURL(value)\n if (!url) return null\n\n const result = {} as Note3URLParts\n\n if (url.protocol === 'note3:') {\n const match = url.pathname.match(RE_NOTE3_URL_PATH)\n if (match) {\n result.share = match[1]\n }\n } else if (url.hash && getKnownNote3Origins().includes(url.origin)) {\n // Parse hash-based Note3 URLs\n const blockMatch = url.hash.match(/^#\\/block\\/([a-z0-9]+)/)\n if (blockMatch) {\n result.focus = blockMatch[1]\n }\n\n const params = searchParamsFromHash(url.hash)\n if (params?.get('share')) {\n result.share = params?.get('share') ?? undefined\n } else if (params?.get('pub')) {\n // backward compatibility: old URLs used ?pub=\n result.share = params?.get('pub') ?? undefined\n } else if (params?.get('preview')) {\n result.share = params?.get('preview') ?? undefined\n result.preview = true\n }\n } else {\n return null\n }\n\n VERBOSE('Parsed Note3 url:', value, result)\n return result\n}\n\n/**\n * Create a Note3 URL with optional share or block parameters\n *\n * @param pub The public share key\n * @param block The block ID to focus on\n * @param previewPub If true, use preview parameter instead of share\n * @param relative If true, return a relative URL without origin/protocol\n * @returns Formatted Note3 URL\n */\nexport function makeNote3Url(\n {\n pub,\n block,\n previewPub = false,\n relative = false,\n }: {\n pub?: string\n block?: string\n previewPub?: boolean\n relative?: boolean\n },\n): string {\n if (!pub && !block) throw new Error('Neither pub nor block - what kind of URL would that be?')\n\n const urlWithoutHash = typeof window !== 'undefined'\n ? `${window.location.origin}${window.location.pathname}`\n : ''\n const baseUrl = relative ? '' : `${urlWithoutHash}#`\n\n if (previewPub) {\n return `${baseUrl}/${block ? `block/${block}` : ''}${pub ? `?preview=${pub}` : ''}`\n } else {\n return `${baseUrl}/${block ? `block/${block}` : ''}${pub ? `?share=${pub}` : ''}`\n }\n}\n\n/**\n * Extract search parameters from the hash portion of a URL\n *\n * Useful for Note3 URLs where parameters appear after ? in the hash\n * e.g., https://note3.app#/block/abc123?share=xyz\n *\n * @param hashPartOfUrl The hash string (defaults to window.location.hash)\n * @returns URLSearchParams or null if no query parameters in hash\n * @deprecated Consider using standard URL parsing instead for new code\n */\nexport function searchParamsFromHash(hashPartOfUrl?: string): URLSearchParams | null {\n const hash = hashPartOfUrl ?? (typeof window !== 'undefined' ? window.location.hash : '')\n const split = hash.split('?', 2)\n return split.length >= 2 ? new URLSearchParams(split[1]) : null\n}\n\n// ============================================================================\n// Query Parameter Handling\n// ============================================================================\n\n/**\n * Replace search parameters in a URL\n *\n * @param location Location-like object with pathname and query\n * @param params Object with key-value pairs to set\n * @returns New URL string with updated parameters\n */\nexport function replaceSearchParamsInUrl(\n location: { pathname?: string; query?: Record<string, string> | string },\n params: Record<string, string | null | undefined>,\n): string {\n const query = typeof location.query === 'string'\n ? new URLSearchParams(location.query)\n : new URLSearchParams(location.query as Record<string, string> ?? {})\n\n Object.entries(params).forEach(([key, value]) => {\n if (value) {\n query.set(key, value)\n } else {\n query.delete(key)\n }\n })\n\n return `${location.pathname || ''}${query.size > 0 ? `?${query.toString()}` : ''}`\n}\n\n/**\n * Merge partial location/URI parts with existing location\n *\n * @param location The current location object\n * @param replace Partial location with fields to replace\n * @returns Full URI string with pathname, search, and hash\n */\nexport function replaceUriParts(\n location: { pathname?: string; search?: string; hash?: string },\n replace: Partial<{ pathname?: string; search?: string; hash?: string }>,\n): string {\n const { pathname, search, hash } = {\n ...location,\n ...replace,\n }\n return `${pathname || ''}${search || ''}${hash || ''}`\n}\n"],"mappings":"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","names":["VERBOSE","g","parseHashFragments","hash","fragments","pairs","pair","key","value","getHashFragment","url","hashFragmentsToString","k","v","setHashFragment","deleteHashFragment","hasHashFragment","CANONICAL_NOTE3_ORIGINS","getKnownNote3Origins","origins","pathname","RE_NOTE3_URL_PATH","tryParseURL","tryParseNote3URL","result","match","blockMatch","params","searchParamsFromHash","makeNote3Url","pub","block","previewPub","relative","urlWithoutHash","baseUrl","hashPartOfUrl","split","replaceSearchParamsInUrl","location","query","replaceUriParts","replace","search"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{a as h,b}from"./chunk-MXMMU6NF.min.js";var L=h(d=>{"use strict";Object.defineProperty(d,"__esModule",{value:!0});var j=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(i){return typeof i}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":typeof i},B=typeof window<"u"&&typeof window.document<"u",I=typeof process<"u"&&process.versions!=null&&process.versions.node!=null,x=(typeof self>"u"?"undefined":j(self))==="object"&&self.constructor&&self.constructor.name==="DedicatedWorkerGlobalScope",A=typeof window<"u"&&window.name==="nodejs"||typeof navigator<"u"&&(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")),J=typeof Deno<"u"&&typeof Deno.version<"u"&&typeof Deno.version.deno<"u";d.isBrowser=B;d.isWebWorker=x;d.isNode=I;d.isJsDom=A;d.isDeno=J});var S=h((_,E)=>{"use strict";E.exports=function(i,e){e||(e={}),typeof e=="function"&&(e={cmp:e});var t=typeof e.cycles=="boolean"?e.cycles:!1,o=e.cmp&&(function(u){return function(r){return function(a,n){var c={key:a,value:r[a]},f={key:n,value:r[n]};return u(c,f)}}})(e.cmp),s=[];return(function u(r){if(r&&r.toJSON&&typeof r.toJSON=="function"&&(r=r.toJSON()),r!==void 0){if(typeof r=="number")return isFinite(r)?""+r:"null";if(typeof r!="object")return JSON.stringify(r);var a,n;if(Array.isArray(r)){for(n="[",a=0;a<r.length;a++)a&&(n+=","),n+=u(r[a])||"null";return n+"]"}if(r===null)return"null";if(s.indexOf(r)!==-1){if(t)return JSON.stringify("__cycle__");throw new TypeError("Converting circular structure to JSON")}var c=s.push(r)-1,f=Object.keys(r).sort(o&&o(r));for(n="",a=0;a<f.length;a++){var m=f[a],g=u(r[m]);g&&(n&&(n+=","),n+=JSON.stringify(m)+":"+g)}return s.splice(c,1),"{"+n+"}"}})(i)}});var p=b(L(),1),R=b(S(),1),F=!1,D=!1;p.isNode&&(process?.env?.LOGGER_TIME_PREFIX&&(F=process?.env?.LOGGER_TIME_PREFIX==="true"),process?.env?.LOGGER_PERF_PREFIX&&(D=process?.env?.LOGGER_PERF_PREFIX==="true"));var k={prefix:void 0,time:F,delta:D,dimDebugOnServer:!0,printOriginOnServer:!0,serverInspectOptions:{},customFormattersOnServer:!0,printStackLinesOnServer:!1,dim:!0},w=[],G=class{sinceFirst=0;sinceLast=0;time=!1;delta=!1;constructor(i,e,t,o){Object.assign(this,{sinceFirst:i,sinceLast:e,time:t,delta:o})}toString(){let i=this.sinceFirst*.001,e=i.toFixed(i<5?2:1),t=this.sinceLast<1e3?`${this.sinceLast.toFixed(0)}`.padStart(5," "):`${`${(this.sinceLast*.001).toFixed(this.sinceLast<1e4?1:0)}`.padStart(4," ")}s`;return`[${[this.time?e:null,this.delta?t:null].filter(o=>o!=null).join(",")}]`}},N=class{constructor(i,e){Object.assign(this,{style:i,string:e})}},y=!1,P=class l{static ERROR=2;static WARN=4;static INFO=6;static LOG=6;static DEBUG=8;static VERBOSE=10;static firstLog=0;static lastLog=0;static setup(e=l.INFO,t={}){t=Object.assign({},k,t),e>10&&console.debug("setup logger",{config:t});let o=this.wrapLog(console.debug,{...t,dim:t.dimDebugOnServer}),s=(...n)=>{typeof window<"u"&&window?.FORCE_DISABLE_LOGLEVEL&&o(...n)};s.isDisabled=!0,s.isEnabled=!1;let u=this.wrapLog(console.groupCollapsed,t),r=(n,c)=>{function f(...g){let v=g[g.length-1];return v===s?v():(u(...g.slice(0,-1)),(async()=>{try{let O=v();return O instanceof Promise?await O:O}finally{console.groupEnd()}})())}let m=Object.assign(c.bind({}),{isEnabled:n,isDisabled:!n,group:f,force:c});return n?m:Object.assign(s.bind({}),{isEnabled:n,isDisabled:!n,group:f,force:m})},a=r(e>=l.ERROR,this.wrapLog(console.error,t));return{ERROR:(...n)=>(a(...n),new Error(n.map(c=>typeof c=="string"?c:(0,R.default)(c)).join(" "))),WARN:r(e>=l.WARN,this.wrapLog(console.warn,t)),LOG:r(e>=l.INFO,this.wrapLog(console.log,t)),DEBUG:r(e>=l.DEBUG,this.wrapLog(console.log,{...t,dim:t.dimDebugOnServer})),VERBOSE:r(e>=l.VERBOSE,this.wrapLog(console.debug,{...t,dim:t.dimDebugOnServer}))}}static wrapLog(e,t){if(p.isNode)return e.bind(console);{let o=[];if(t.time||t.delta){let s=p.isBrowser&&navigator.userAgent.includes("Chrome")?["",l.timeStr(!!t.time,!!t.delta)]:[];o.push(...s)}return t.prefix&&(y?o.push(new N("dim",t.prefix)):o.push(t.prefix)),e.bind(console,...o)}}static timeStr(e,t,o=0){if(!performance.now)return;let s=performance.now();l.firstLog||(l.firstLog=s,l.lastLog=s);let u=new G(s-l.firstLog,s-l.lastLog,e,t);return l.lastLog=s,o?u.toString():u}static getOriginFromStack(e){let t=!1;for(let o of e.split(`
|
|
2
|
+
`)){let s=o.match(/^\s+at\s+(.*)/);if(s){if(t)return s[1].trim().replace(__dirname,"");t=!0}}}};p.isBrowser&&(window.devtoolsFormatters=window.devtoolsFormatters??[],window.devtoolsFormatters.push({header:i=>{if(w&&w.length){for(let e of w)if(e.match(i))return["span",{},e.format(i)]}return null},hasBody:()=>!0},{header:i=>{if(!(i instanceof G))return null;y||(y=!0);let e=P.timeStr(i.time,i.delta);return["span",{style:"font-weight: light; color: grey"},e?.toString()]},hasBody:()=>!1},{header:i=>i instanceof N?(y||(y=!0),["span",{style:"font-weight: light; color: grey; "},i.string]):null,hasBody:()=>!1}));export{P as a};
|
|
3
|
+
//# sourceMappingURL=chunk-5TTMWYXD.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../node_modules/.pnpm/browser-or-node@2.1.1/node_modules/browser-or-node/lib/index.js","../../../../node_modules/.pnpm/fast-json-stable-stringify@2.1.0/node_modules/fast-json-stable-stringify/index.js","../../../../node_modules/.pnpm/besonders-logger@1.0.2/node_modules/besonders-logger/src/lib/logger.ts"],"sourcesContent":["\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nvar isBrowser = typeof window !== \"undefined\" && typeof window.document !== \"undefined\";\n\nvar isNode = typeof process !== \"undefined\" && process.versions != null && process.versions.node != null;\n\nvar isWebWorker = (typeof self === \"undefined\" ? \"undefined\" : _typeof(self)) === \"object\" && self.constructor && self.constructor.name === \"DedicatedWorkerGlobalScope\";\n\n/**\n * @see https://github.com/jsdom/jsdom/releases/tag/12.0.0\n * @see https://github.com/jsdom/jsdom/issues/1537\n */\nvar isJsDom = typeof window !== \"undefined\" && window.name === \"nodejs\" || typeof navigator !== \"undefined\" && (navigator.userAgent.includes(\"Node.js\") || navigator.userAgent.includes(\"jsdom\"));\n\nvar isDeno = typeof Deno !== \"undefined\" && typeof Deno.version !== \"undefined\" && typeof Deno.version.deno !== \"undefined\";\n\nexports.isBrowser = isBrowser;\nexports.isWebWorker = isWebWorker;\nexports.isNode = isNode;\nexports.isJsDom = isJsDom;\nexports.isDeno = isDeno;","'use strict';\n\nmodule.exports = function (data, opts) {\n if (!opts) opts = {};\n if (typeof opts === 'function') opts = { cmp: opts };\n var cycles = (typeof opts.cycles === 'boolean') ? opts.cycles : false;\n\n var cmp = opts.cmp && (function (f) {\n return function (node) {\n return function (a, b) {\n var aobj = { key: a, value: node[a] };\n var bobj = { key: b, value: node[b] };\n return f(aobj, bobj);\n };\n };\n })(opts.cmp);\n\n var seen = [];\n return (function stringify (node) {\n if (node && node.toJSON && typeof node.toJSON === 'function') {\n node = node.toJSON();\n }\n\n if (node === undefined) return;\n if (typeof node == 'number') return isFinite(node) ? '' + node : 'null';\n if (typeof node !== 'object') return JSON.stringify(node);\n\n var i, out;\n if (Array.isArray(node)) {\n out = '[';\n for (i = 0; i < node.length; i++) {\n if (i) out += ',';\n out += stringify(node[i]) || 'null';\n }\n return out + ']';\n }\n\n if (node === null) return 'null';\n\n if (seen.indexOf(node) !== -1) {\n if (cycles) return JSON.stringify('__cycle__');\n throw new TypeError('Converting circular structure to JSON');\n }\n\n var seenIndex = seen.push(node) - 1;\n var keys = Object.keys(node).sort(cmp && cmp(node));\n out = '';\n for (i = 0; i < keys.length; i++) {\n var key = keys[i];\n var value = stringify(node[key]);\n\n if (!value) continue;\n if (out) out += ',';\n out += JSON.stringify(key) + ':' + value;\n }\n seen.splice(seenIndex, 1);\n return '{' + out + '}';\n })(data);\n};\n","import { isBrowser, isNode } from 'browser-or-node'\nimport stringify from 'fast-json-stable-stringify'\n\n////////////\n// CONFIG //\n////////////\n\n//(i) disabled by default bc. the detection logic has disappeared after the refactor.\n//TODO: Find it and check if it works\nlet TIME_PREFIX_ENABLED = false\nlet PERFORMANCE_PREFIX_ENABLED = false\nif (isNode) {\n // console.debug('isNode checking', { process })\n if (process?.env?.LOGGER_TIME_PREFIX) TIME_PREFIX_ENABLED = process?.env?.LOGGER_TIME_PREFIX === 'true'\n if (process?.env?.LOGGER_PERF_PREFIX) PERFORMANCE_PREFIX_ENABLED = process?.env?.LOGGER_PERF_PREFIX === 'true'\n}\nexport let LOGGER_DEFAULT_CONFIG = {\n prefix: undefined as string | undefined,\n time: TIME_PREFIX_ENABLED,\n delta: PERFORMANCE_PREFIX_ENABLED,\n dimDebugOnServer: true,\n printOriginOnServer: true,\n serverInspectOptions: {},\n customFormattersOnServer: true,\n // Depth of stacktrace to show on server\n // - integer saying how many lines\n // - false to disable, true for all\n printStackLinesOnServer: false as boolean | number,\n dim: true,\n}\n\nexport type Config = Partial<typeof LOGGER_DEFAULT_CONFIG>\nexport type ConsoleFx = (...data: any[]) => void\nexport const StringFormatters = [\n // Format to string (Client console - currently not on server)\n // {\n // match: obj => obj instanceof Model,\n // format: m => {\n // const { displayName } = m\n // return `${m.constructor.name}#${m.ID}${displayName ? `{${displayName}}` : ''}`\n // },\n // },\n] as unknown as {\n match: (obj: any) => boolean\n format: (m: any) => string\n}[]\n\n// let applyCustomFormatters;\n// applyCustomFormatters = (value, config) => {\n// for (const formatter of StringFormatters) {\n// if (formatter.match(value)) return formatter.format(value);\n// }\n// if (!_.isString(value)) {\n// return util.inspect(value, config.inspectOptionsOnServer);\n// }\n// return value;\n// };\n\n/// ////////////////\n// RUNTIME STUFF //\n/// ////////////////\n\nexport class LoggerTime {\n sinceFirst = 0\n sinceLast = 0\n time = false\n delta = false\n constructor(sinceFirst: number, sinceLast: number, time: boolean, delta: boolean) {\n Object.assign(this, { sinceFirst, sinceLast, time, delta })\n }\n\n toString() {\n const sinceFirstNum = (this.sinceFirst * 0.001)\n const sinceFirst = sinceFirstNum.toFixed(sinceFirstNum < 5 ? 2 : 1) /* .padStart(3, ' ') */\n const sinceLast\n = this.sinceLast < 1000 // when >= 1s, format as seconds\n ? `${this.sinceLast.toFixed(0)}`.padStart(5, ' ')\n : `${`${(this.sinceLast * 0.001).toFixed(this.sinceLast < 10000 ? 1 : 0)}`.padStart(4, ' ')}s`\n return `[${[this.time ? sinceFirst : null, this.delta ? sinceLast : null]\n .filter(t => t != null)\n .join(',')}]`\n }\n}\n\nexport class Style {\n constructor(style: string, string: string) {\n Object.assign(this, { style, string })\n }\n}\nlet formattersEnabled = false // for tracking if chrome formatters are enabled (don't change manually)\n\nexport class Logger {\n static ERROR = 2 as const\n static WARN = 4 as const\n static INFO = 6 as const // alias for LOG\n static LOG = 6 as const\n static DEBUG = 8 as const\n static VERBOSE = 10 as const\n\n static firstLog = 0\n static lastLog = 0\n\n /**\n * This is a clever way to log without the extra check on each log line.\n * Use it like this:\n * ```\n * const { WARN, LOG, DEBUG, VERBOSE } = Logger.setup(Logger.INFO); // eslint-disable-line no-unused-vars\n * LOG('message', data);\n * DEBUG(this.collectionName, '...')\n * if (!VERBOSE.isDisabled) {\n * const verboseStuff = generateVerboseStuff(); // computationally intensive\n * VERBOSE('Here it is:', verboseStuff)\n * }\n * ```\n *\n * @ param {number} level See {@link LVs}\n * @ param {object} config see LOGGER_DEFAULT_CONFIG\n * @ typedef {Function & {isDisabled: boolean, isEnabled: boolean, ...}} LogFunc\n * @ returns {{LOG: LogFunc, VERBOSE: LogFunc, DEBUG: LogFunc, WARN: LogFunc, ERROR: LogFunc}}\n */\n static setup(level: 2 | 4 | 6 | 8 | 10 = Logger.INFO, config: Config = {}) {\n config = Object.assign({}, LOGGER_DEFAULT_CONFIG, config) // defaults(config, LOGGER_DEFAULT_CONFIG) // fyi this is like the reverse of Object.assign\n if (level > 10) console.debug('setup logger', { config }) // manual overide to level:11 to show this trace\n\n const debugLogForStub = this.wrapLog(console.debug, { ...config, dim: config.dimDebugOnServer })\n const stub = (...args: any[]) => {\n // @ts-expect-error hack to enable DEBUG logging EVERYWHERE\n if (typeof window !== 'undefined' && window?.FORCE_DISABLE_LOGLEVEL)\n debugLogForStub(...args)\n } // For disabled log-levels, we just return a stub function\n stub.isDisabled = true // this makes it possible to check, e.g. `DEBUG.isDisabled`\n stub.isEnabled = false // depending on syntactic preference\n const groupCollapsed = this.wrapLog(console.groupCollapsed, config)\n\n const addExtraFxs = (enabled: boolean, func: (...T: any) => void) =>/* : ((...T) => void & {isDisabled: boolean}) */ {\n // warning - weird TS hacks approaching:\n function group<T extends Func>(\n ...args: [...any[], T]\n ): ReturnType<T> extends Promise<any> ? Promise<ReturnType<T>> : ReturnType<T> {\n const functionToWrap = args[args.length - 1] as T\n\n if (functionToWrap as Func === stub)\n return functionToWrap() as ReturnType<T>\n\n groupCollapsed(...args.slice(0, -1)) // except last\n\n const asyncWrapper = async () => {\n try {\n const result = functionToWrap()\n return result instanceof Promise ? await result : result\n } finally {\n console.groupEnd()\n }\n }\n\n return asyncWrapper() as ReturnType<T> // Cast to bypass the Promise type inference\n }\n\n const realFunc = Object.assign(\n func.bind({}), // clone function - https://stackoverflow.com/a/6772648\n {\n isEnabled: enabled,\n isDisabled: !enabled,\n group,\n force: func,\n },\n )\n if (enabled) {\n return realFunc\n } else {\n return Object.assign(\n stub.bind({}), // clone stub function - https://stackoverflow.com/a/6772648\n {\n isEnabled: enabled,\n isDisabled: !enabled,\n group,\n force: realFunc,\n },\n )\n }\n }\n\n const ERRFX = addExtraFxs(level >= Logger.ERROR, this.wrapLog(console.error, config))\n const ERROR = (...params: any[]) => {\n ERRFX(...params)\n // return so we can log & throw in one go\n return new Error(params.map(param => {\n return typeof param === 'string' ? param : stringify(param) // stringify is fast & safe with circular references\n }).join(' '))\n }\n\n // console.debug(\"Logger init:\", config)\n return {\n ERROR,\n WARN: addExtraFxs(level >= Logger.WARN, this.wrapLog(console.warn, config)),\n LOG: addExtraFxs(level >= Logger.INFO, this.wrapLog(console.log, config)),\n DEBUG: addExtraFxs(level >= Logger.DEBUG, this.wrapLog(console.log, { ...config, dim: config.dimDebugOnServer })), // not using console.debug as that requires dev tools verbose to be enabled\n VERBOSE: addExtraFxs(level >= Logger.VERBOSE, this.wrapLog(console.debug, { ...config, dim: config.dimDebugOnServer })),\n }\n }\n\n static wrapLog(logFunc: ConsoleFx, config: Config) {\n if (!isNode) {\n // ℹ In browser we can only do some of the fancy things, because we cannot call console.log ourselves,\n // as that would pollute the stacktrace\n\n // ℹ Would be nice to get formtted links in devtools, but <a> tags are not allowed:\n // const stack = new Error().stack;\n // const origin = Logger.getOriginFromStack(stack);\n // const originFilename = origin.split('\\\\').pop().split('/').pop(); // eslint-disable-line\n // if (origin) fixedArgs.push({ link: originFilename, href: `http://localhost:63342/api/file/${origin}` });\n\n // on the client, we need to return the original log function, as otherwise the origin of the log is set to here\n // But luckily we can bind fixed parameters on the function:\n const fixedArgs = []\n // if the custom formatters are enabled, and we want performance logging - we add an instance of P as a static prefix\n if (config.time || config.delta) {\n const isChrome = isBrowser && navigator.userAgent.includes('Chrome')\n\n const p = isChrome\n ? ['', Logger.timeStr(!!config.time, !!config.delta)] // this is a placeholder that gets replaced by the custom formatter\n : [] // [{ get perfNiceTry () { return Logger.timeStr(,,true) } }] // this (of course) shows the time when you click the getter\n fixedArgs.push(...p) // if we start with a non-string, all strings are rendered with quotes :/\n }\n if (config.prefix) {\n if (formattersEnabled)\n fixedArgs.push(new Style('dim', config.prefix))\n else fixedArgs.push(config.prefix)\n }\n // console.log('logger-log', { config, fixedArgs })\n return logFunc.bind(console, ...fixedArgs)\n } else {\n // ℹ in nodejs we print the stack trace origin ourselves, so we can do a lot more things\n // TODO: re-import removed code - https://gitlab.com/onezoomin/ztax/ztax/-/commit/f6f9bde617cd9ae93d1bc4bc49a4b5275e4cbff2#b1d1e091ca27ae560becf7ae1b27a4d53d39c061\n return logFunc.bind(console)\n }\n }\n\n // static log(msg, logPerformance = true) {\n // const p = this.perf();\n // return logPerformance ? `${p} ${msg}` : msg;\n // }\n\n static timeStr(time: boolean, delta: boolean, returnAsString = 0): LoggerTime | string | undefined {\n if (!performance.now)\n return undefined // TODO: server? p = { now: require('performance-now') };\n const now = performance.now()\n if (!Logger.firstLog) {\n Logger.firstLog = now\n Logger.lastLog = now\n }\n const p = new LoggerTime(now - Logger.firstLog, now - Logger.lastLog, time, delta)\n Logger.lastLog = now\n return returnAsString ? p.toString() : p\n }\n\n // (for nodejs) ~ https://stackoverflow.com/a/47296370/1633985\n static getOriginFromStack(stack: any): string | undefined {\n let skippedFirst = false // the first one is Logger.js\n for (const line of stack.split('\\n')) {\n const matches = line.match(/^\\s+at\\s+(.*)/)\n if (matches) {\n if (skippedFirst) {\n // first line - current function\n // second line - caller (what we are looking for)\n return (\n matches[1]\n .trim() // Removes spaces\n // .replace(/^module /, '') // Removes 'module ' at beginning\n // .replace(/^at /, '') // Removes 'at ' at beginning\n // .replace(/^ \\(/, '') // Removes parentheseses around file\n // .replace(/\\)$/, '') // -||-\n .replace(__dirname, '') // Removes script folder path (if exists)\n )\n }\n skippedFirst = true\n }\n }\n }\n}\n\nif (isBrowser) { // isBrowser is not true for web workers\n // CLIENT or Worker //\n\n // @ts-expect-error window hack\n window.devtoolsFormatters = window.devtoolsFormatters ?? []\n // noinspection JSUnusedGlobalSymbols\n // @ts-expect-error window hack\n window.devtoolsFormatters.push(\n {\n // Custom formatters\n header: (obj: any) => {\n if (StringFormatters && StringFormatters.length) {\n for (const formatter of StringFormatters) {\n if (formatter.match(obj))\n return ['span', {}, formatter.format(obj)]\n }\n }\n return null\n },\n hasBody: () => true,\n },\n {\n // Performance object //\n // This is a sneaky way to show performance info withouth any extra calls when logging:\n // LOG(`...`)\n // it would work without this if we would have some way to intercept the call:\n // L.INFO('...') - a getter on L that adds the current time as prefix\n // LOG('...')() - returns the log function with all argumends bound\n // But instead we are adding a custom formatter that replaced the placeholder object of class P with the performance info\n header: (obj: any) => {\n if (!(obj instanceof LoggerTime))\n return null\n if (!formattersEnabled)\n formattersEnabled = true\n const p = Logger.timeStr(obj.time, obj.delta)\n return [\n 'span',\n { style: 'font-weight: light; color: grey' },\n p?.toString(),\n // ['a', { href: 'vscodium://file/home/manu/dev/tamera/bookr/imports/lib/utils/Logger.js' }, 'WOW'],\n ]\n },\n hasBody: () => false,\n },\n {\n // Style object\n header: (obj: { string: any }) => {\n if (!(obj instanceof Style))\n return null\n if (!formattersEnabled)\n formattersEnabled = true\n return ['span', { style: 'font-weight: light; color: grey; '/* font-style: italic; */ }, obj.string]\n },\n hasBody: () => false,\n },\n )\n}\nelse if (isNode) {\n // SERVER //\n // node stuff removed as it breaks/bloats webworker build\n}\n\nexport function logriniTest(): string {\n return 'logrini'\n}\n\ntype Func<T = any> = () => T\n"],"mappings":"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","names":["require_lib","__commonJSMin","exports","_typeof","obj","isBrowser","isNode","isWebWorker","isJsDom","isDeno","require_fast_json_stable_stringify","__commonJSMin","exports","module","data","opts","cycles","cmp","f","node","b","aobj","bobj","seen","stringify","i","out","seenIndex","keys","key","value","import_browser_or_node","import_fast_json_stable_stringify","TIME_PREFIX_ENABLED","PERFORMANCE_PREFIX_ENABLED","isNode","LOGGER_DEFAULT_CONFIG","StringFormatters","LoggerTime","sinceFirst","sinceLast","time","delta","sinceFirstNum","t","Style","style","string","formattersEnabled","Logger","_Logger","level","config","debugLogForStub","stub","args","groupCollapsed","addExtraFxs","enabled","func","group","functionToWrap","result","realFunc","ERRFX","params","param","stringify","logFunc","fixedArgs","p","isBrowser","returnAsString","now","stack","skippedFirst","line","matches","obj","formatter"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/map.ts"],"sourcesContent":["export class SetMap<K, V = K> extends Map<K, Set<V>> {\n\tadd(key: K, value: V) {\n\t\tthis.emplace(key, {\n\t\t\tinsert: () => new Set([value]),\n\t\t\tupdate: (s) => {\n\t\t\t\ts.add(value)\n\t\t\t\treturn s\n\t\t\t},\n\t\t})\n\t}\n\n\taddAll(key: K, values: Array<V>) {\n\t\tthis.emplace(key, {\n\t\t\tinsert: () => new Set(values),\n\t\t\tupdate: (s) => {\n\t\t\t\tvalues.forEach(s.add.bind(s))\n\t\t\t\treturn s\n\t\t\t},\n\t\t})\n\t}\n}\n"],"mappings":"AAAO,IAAMA,EAAN,cAA+B,GAAe,CACpD,IAAIC,EAAQC,EAAU,CACrB,KAAK,QAAQD,EAAK,CACjB,OAAQ,IAAM,IAAI,IAAI,CAACC,CAAK,CAAC,EAC7B,OAASC,IACRA,EAAE,IAAID,CAAK,EACJC,EAET,CAAC,CACF,CAEA,OAAOF,EAAQG,EAAkB,CAChC,KAAK,QAAQH,EAAK,CACjB,OAAQ,IAAM,IAAI,IAAIG,CAAM,EAC5B,OAASD,IACRC,EAAO,QAAQD,EAAE,IAAI,KAAKA,CAAC,CAAC,EACrBA,EAET,CAAC,CACF,CACD","names":["SetMap","key","value","s","values"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{A as Z,B as C,a as M,b as _,c as q,d as E,e as J,f as A,g as H,h as T,i as B,j as W,k as j,l as u,m as F,n as $,o as k,p as h,q as V,r as f,s as Q,t as X,u as Y,w as G,y as x,z as w}from"./chunk-YXZYW2WJ.min.js";var{WARN:ue,LOG:we,DEBUG:de,VERBOSE:U,ERROR:Oe}=W.setup(W.INFO),pe=f("queryDivergencesByPrev",function(e){de(`queryDivergencesByPrev<${e.nameAndSizeUntracked}>`),e.filters.includes("lastWriteWins")&&ue("queryDivergencesByPrev on thread lastWriteWins",e);let t=h(()=>{let s=new Map,i=new Set;U("all applogs:",e.applogs);for(let n of e.applogs){let a;n.pv&&(a=n.pv&&s.get(n.pv.toString()),i.delete(n.pv.toString())),U("traversing log",{log:n,prevLogs:a,leafs:Array.from(i)}),s.set(n.cid,a?[...a,n]:[n]),i.add(n.cid)}return Array.from(i).map(n=>{let a=new C(u({caller:"DivergenceLeaf",thread:e,pattern:`leaf: ${n}`}),s.get(n),e.filters,!0);return{log:a.latestLog,thread:a}})},{name:u({caller:"queryDivergencesByPrev",thread:e})});return U.isDisabled||A(()=>U("[queryDivergencesByPrev] result:",T(t))),t},{equals:M.structural});var ee=class{constructor(r,e,t=null){this.logsOfThisNode=r,this.variables=e,this.prevNode=t,B(this,{threadOfTrail:q})}get record(){return this.variables}get threadOfTrail(){return this.prevNode?x([this.logsOfThisNode,this.prevNode.threadOfTrail]):this.logsOfThisNode}get trailLogs(){return this.threadOfTrail.applogs}},P=class{constructor(r){this.nodes=r,B(this,{threadOfAllTrails:q,size:q,isEmpty:q})}get size(){return this.records.length}get isEmpty(){return this.records.length===0}get untrackedSize(){return E(()=>this.records.length)}get records(){return h(()=>this.nodes.map(({variables:r})=>r),{name:"QueryResult.records"})}get leafNodeThread(){return x(h(()=>this.nodes.map(({logsOfThisNode:r})=>r),{name:"QueryResult.leafNodeThread"}))}get leafNodeLogSet(){return h(()=>this.nodes.map(({logsOfThisNode:r})=>r.applogs),{name:"QueryResult.leafNodeLogSet"})}get leafNodeLogs(){return h(()=>this.nodes.flatMap(({logsOfThisNode:r})=>r.applogs),{name:"QueryResult.leafNodeLogs"})}get threadOfAllTrails(){return x(h(()=>this.nodes.map(r=>r.threadOfTrail),{name:"QueryResult.threadOfAllTrails"}))}get thread(){return this.threadOfAllTrails}get allApplogs(){return this.threadOfAllTrails.applogs}},{WARN:Te,LOG:I,DEBUG:N,VERBOSE:o,ERROR:O}=W.setup(W.INFO,{prefix:"[q]"}),L=null,ce=f("lastWriteWins",function(e,{inverseToOnlyReturnFirstLogs:t,tolerateAlreadyFiltered:s}={}){if(o(`lastWriteWins${t?".inversed":""} < ${e.nameAndSizeUntracked} > initializing`),e.filters.includes("lastWriteWins")){if(s)return N("[lastWriteWins] already filtered, but tolerateAlreadyFiltered=true, so returning"),e;throw O("thread already filtered lastWriteWins:",e.filters,{name:e.name})}let i,n=Z(e,function(l,y){let p=Q(l),c,v=[],m=p?null:[];p?(i=new Map,c=l.init):c=l.added;let b;for(let g=t?0:c.length-1;t?g<c.length:g>=0;t?g++:g--){let d=c[g],z=d.en+"|"+d.at;if(b&&(t?b>d.ts:b<d.ts))throw O("lastWriteWins.mapper logs not sorted:",b,t?">":"<",d.ts,{log:d,i:g,newLogs:c,inverseToOnlyReturnFirstLogs:t});b=d.ts;let S=i.get(z);(!S||(t?S.ts>d.ts:S.ts<d.ts))&&(S&&!p&&m.push(S),v.push(d),i.set(z,d))}return Y(v),o.isDisabled||o(`lastWriteWins${t?".inversed":""}<${e.nameAndSizeUntracked}> mapped event`,p?{...Object.fromEntries(Object.entries(l).map(([g,d])=>[g,d?.length])),toAdd:v.length,toRemove:m}:{...l,toAdd:v,toRemove:m}),p?{init:v}:{added:v,removed:m}},{name:`lastWriteWins${t?".inversed":""}`,extraFilterName:"lastWriteWins"});return o.isDisabled||A(()=>{o(`lastWriteWins<${e.nameAndSizeUntracked}> filtered down to`,n.applogs.length)}),n},{equals:$,argsDebugName:r=>u({caller:"lastWriteWins",thread:r})}),fe=f("withoutDeleted",function(e){if(o.isEnabled&&o(`withoutDeleted<${e.nameAndSizeUntracked}>`),e.filters.includes("withoutDeleted"))throw O("thread already filtered withoutDeleted:",e.filters,{name:e.name});let t=w(e,{at:["isDeleted","relation/isDeleted","block/isDeleted"],vl:!0},{name:"isDeleted"});o.isEnabled&&o(`withoutDeleted<${e.nameAndSizeUntracked}> deletionLogs:`,E(function(){return[...t.applogs]}));let s=u({caller:"allDeletedEntities",thread:e}),i=V(function(){return t.map(a=>a.en)},{name:s});return o.isEnabled&&A(()=>{o(`withoutDeleted<${e.nameAndSizeUntracked}> deleted:`,[...i])}),w(e,{"!en":i},{name:"withoutDeleted",extraFilterName:"withoutDeleted"})},{equals:$}),D=f("query",function r(e,t,s={},i={}){le();let n=K(e);N(`query<${n.nameAndSizeUntracked}>:`,t);let a=Array.isArray(t)?t:[t],l;if(a.length===1)l=null;else{let c=a.slice(0,-1);l=r(n,c,s,i)}let y=a[a.length-1],p=te(n,l,y,i);return o.isDisabled||A(()=>o("query result:",T(p))),p},{equals:k,argsDebugName:(r,e,t)=>u({caller:"query",thread:r,args:t?{pattern:e,startVars:t}:e})}),te=f("queryStep",function(e,t,s,i={}){if(N(`queryStep<${e.nameAndSizeUntracked}> with`,t?.untrackedSize??"all","nodes, pattern:",s),!Object.entries(s).length)throw new Error("Pattern is empty");function n(l){let[y,p]=G(s,l?.variables??{});o("[queryStep.doQuery] patternWithoutVars: ",y);let c=w(e,y),v=R(p),m=h(function(){let g=c.map(d=>({log:d,vars:v(d)}));return o.isEnabled&&o("[queryStep.doQuery] step node:",l?.variables," =>",g,"from:",E(()=>c.applogs)),g.map(({log:d,vars:z})=>{let S=Object.assign({},l?.variables,z);return new ee(X.fromArray([d],u({caller:"QueryNode",thread:c,pattern:`${j(S)}@${j(y)}`})),S,l)})},{name:u({caller:"doQuery.mapNodes",thread:c,pattern:s})});return o.isEnabled&&A(()=>o("[queryStep.doQuery] resultNodes:",[...m])),i.debug&&I("[queryStep] step result:",E(()=>m.map(({variables:b,logsOfThisNode:g})=>({variables:b,thread:g})))),m}let a=h(function(){return N(`[queryStep] Running with ${t?.nodes?.length} input nodes:`),t?[...t.nodes.flatMap(n)]:[...n(null)]},{name:u({caller:"queryStep",thread:e,pattern:s})});return o.isEnabled&&A(()=>o("[queryStep] observableResultNodes:",[...a])),new P(a)},{equals:k,argsDebugName:(r,e,t)=>u({caller:"queryStep",thread:r,pattern:t})}),ge=f("queryNot",function(e,t,s,i={}){let n=t.nodes;N(`queryNot<${e.nameAndSizeUntracked}> from: ${n.length} nodes`);let a=Array.isArray(s)?s:[s];for(let l of a){if(!Object.entries(s).length)throw new Error("Pattern is empty");n=n.filter(function({variables:p}){let[c,v]=G(l,p??{});o("[queryNot] patternWithoutVars: ",c);let m=w(e,c);return o("[queryNot] step node:",p," =>",m.size,"applogs"),o.isDisabled||o("[queryNot] step node:",p," => empty?",E(()=>m.applogs)),i.debug&&I("[queryNot] node result:",p,"=>",m.applogs),m.isEmpty})}return new P(n)},{equals:k,argsDebugName:(r,e,t)=>u({caller:"queryNot",thread:r,pattern:t})}),ye=f("filterAndMap",function(e,t,s){N(`filterAndMap<${e.nameAndSizeUntracked}>`,t);let i=w(e,t);o.isEnabled&&(o("[filterAndMap] filtered:",i.untrackedSize),A(()=>o("[filterAndMap] filtered:",i.applogs)));let n=u({thread:e,pattern:t,caller:"filterAndMap"}),a=h(()=>se(i,s),{name:n});return o.isDisabled||A(()=>o("[filterAndMap] mapped:",a)),a},{equals:M.structural,argsDebugName:(r,e)=>u({caller:"filterAndMap",thread:r,pattern:e})}),me=f("queryAndMap",function(e,t,s,i={}){let n=K(e);N(`queryAndMap<${n.nameAndSizeUntracked}>`,{patternOrPatterns:t,variables:i,map:s});let a=u({thread:n,caller:"queryAndMap"}),l=D(n,t);o("[queryAndMap] filtered count:",l.untrackedSize);let y=h(()=>ie(l,s),{name:a});return o.isDisabled||A(()=>o("[queryAndMap] result:",T(y))),y},{equals:M.structural,argsDebugName:(r,e)=>u({caller:"queryAndMap",thread:r,pattern:e})}),he=f("queryEntity",function(e,t,s,i){N(`queryEntity<${e.nameAndSizeUntracked}>`,s,t);let n=w(e,{en:s,at:ae(t,i)});return o("queryEntity applogs:",n.applogs),q(()=>n.isEmpty?null:Object.fromEntries(n.map(({at:a,vl:l})=>[a.slice(t.length+1),l])))},{equals:F,argsDebugName:(r,e,t)=>u({caller:"queryEntity",thread:r,args:{name:e,entityID:t}})}),ve=f("agentsOfThread",function(e){N(`agentsOfThread<${e.nameAndSizeUntracked}>`);let t=_.map(),s=J(n=>{for(let a of Q(n)?n.init:n.added){let l=t.get(a.ag)??0;t.set(a.ag,l+1)}for(let a of!Q(n)&&n.removed||[]){let l=t.get(a.ag);if(!l||l<1)throw O("[agentsOfThread] number is now negative",{log:a,event:n,mapped:t,prev:l});t.set(a.ag,l-1)}I(`agentsOfThread<${e.nameAndSizeUntracked}> processed event`,{event:n,mapped:t})});s({init:e.applogs});let i=e.subscribe(s);return H(t,i),t}),re=f("entityOverlap",function(e,t){return I(`entityOverlap<${e.nameAndSizeUntracked}, ${t.nameAndSizeUntracked}>`),q(()=>{let s=new Set(e.map(n=>n.en)),i=new Set(t.map(n=>n.en));return[...s].filter(n=>i.has(n))})});var Ae=f("entityOverlapCount",function(e,t){return q(()=>re(e,t).get().length)}),ne=f("querySingle",function(e,t,s={}){let i=D(e,t,s);return q(()=>{if(i.isEmpty)return null;if(i.size>1)throw O("[querySingle] got",i.size,"results:",i);let n=i.nodes[0].logsOfThisNode;if(n.size!=1)throw O("[querySingle] single result, but got",n.size,"logs:",n.applogs);return n.applogs[0]})},{equals:M.structural,argsDebugName:(r,e)=>u({caller:"querySingle",thread:r,pattern:e})}),be=f("querySingleAndMap",function(e,t,s,i={}){let n=ne(e,t,i);return q(()=>{let a=n.get();if(a)return typeof s=="string"?a[s]:R(s)(a)})},{equals:M.structural,argsDebugName:(r,e)=>u({caller:"querySingleAndMap",thread:r,pattern:e})}),se=function(e,t){return typeof t=="function"?e.map(t):typeof t=="string"?e.map(s=>s[t]):e.map(R(t))},ie=function(e,t){return typeof t=="function"?e.records.map(t):typeof t=="string"?e.nodes.map(s=>{if(!Object.hasOwn(s.record,t)){if(s.logsOfThisNode.size!==1)throw O(`not sure what to map (it's not a var and a result node log count of ${s.logsOfThisNode.size})`);return s.logsOfThisNode.firstLog[t]}return s.record[t]}):e.nodes.map(s=>R(t)(e))};function R(r){return e=>Object.entries(r).reduce((t,[s,i])=>(t[i]=e[s],t),{})}function ae(r,e){return e.map(t=>oe(r,t))}function oe(r,e){return`${r}/${e}`}function K(r,e){return Array.isArray(r)?C.fromArray(r,e||`threadFromArray[${r.length}]`,!0):r}function le(){if(L!=null&&performance.now()>=L)throw new qe(L)}var qe=class extends Error{constructor(r){super(r)}};function Ne(r,e,t,s){let i=function(a,l,y){if(y.includes(a))throw new Error(`[mapAndRecurseKids.loop] Circular reference detected: ${a}`);if(y.length>42)throw new Error("[mapAndRecurseKids.maxDepth] Maximum recursion depth (42) exceeded");let p=t({blockID:a,relID:l}),v=D(r,[{en:"?kidRelID",at:"relation/childOf",vl:a},{en:"?kidRelID",at:"relation/block",vl:"?kidID"}]).records.map(function({kidID:b,kidRelID:g}){return i(b,g,[...y,a])});return s(p,v)};return i(e,null,[])}function tt(r,e){let t=[];return Ne(r,e,({blockID:s,relID:i})=>{let n=D(r,[{en:s}]);if(t.push(...n.threadOfAllTrails.applogs),i){let a=D(r,[{en:i}]);t.push(...a.threadOfAllTrails.applogs)}},(s,i)=>{}),t}export{Ne as a,tt as b};
|
|
2
|
+
//# sourceMappingURL=chunk-KFV32MHC.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../@wovin/core/src/query/divergences.ts","../../../@wovin/core/src/query/matchers.ts","../../../@wovin/core/src/query/types.ts","../../../@wovin/core/src/query/basic.ts","../src/applog-collection.ts"],"sourcesContent":["import { Logger } from 'besonders-logger'\nimport { autorun, comparer, toJS } from 'mobx'\nimport stringify from 'safe-stable-stringify'\nimport { Applog, CidString } from '../applog/datom-types'\nimport { computedFnDeepCompare, createDebugName, observableArrayMap } from '../mobx/mobx-utils'\nimport { Thread } from '../thread/basic'\nimport { ThreadInMemory } from '../thread/writeable'\n\nconst { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line no-unused-vars\n\nexport interface DivergenceLeaf {\n\tlog: Applog\n\tthread: Thread\n}\n\nexport const queryDivergencesByPrev = computedFnDeepCompare('queryDivergencesByPrev', function queryConflictingByPrev(\n\tsourceThread: Thread,\n) {\n\tDEBUG(`queryDivergencesByPrev<${sourceThread.nameAndSizeUntracked}>`)\n\tif (sourceThread.filters.includes('lastWriteWins')) WARN(`queryDivergencesByPrev on thread lastWriteWins`, sourceThread)\n\n\tconst divergences = observableArrayMap(() => {\n\t\tconst logsForNode = new Map<CidString, Applog[]>()\n\t\tconst leafs = new Set<CidString>()\n\t\tVERBOSE('all applogs:', sourceThread.applogs)\n\t\tfor (const log of sourceThread.applogs) {\n\t\t\tlet prevLogs\n\t\t\tif (log.pv) {\n\t\t\t\tprevLogs = log.pv && logsForNode.get(log.pv.toString())\n\t\t\t\tleafs.delete(log.pv.toString())\n\t\t\t}\n\t\t\tVERBOSE('traversing log', { log, prevLogs, leafs: Array.from(leafs) })\n\t\t\tlogsForNode.set(log.cid, prevLogs ? [...prevLogs, log] : [log])\n\t\t\tleafs.add(log.cid)\n\t\t}\n\t\treturn Array.from(leafs).map(leafID => {\n\t\t\t// TODO use MappedThread?\n\t\t\tconst thread = new ThreadInMemory(\n\t\t\t\tcreateDebugName({\n\t\t\t\t\tcaller: 'DivergenceLeaf',\n\t\t\t\t\tthread: sourceThread,\n\t\t\t\t\tpattern: `leaf: ${leafID}`,\n\t\t\t\t}),\n\t\t\t\tlogsForNode.get(leafID),\n\t\t\t\tsourceThread.filters,\n\t\t\t\ttrue,\n\t\t\t\t// TODO: sourceThread,\n\t\t\t)\n\t\t\treturn ({ log: thread.latestLog, thread })\n\t\t})\n\t}, { name: createDebugName({ caller: 'queryDivergencesByPrev', thread: sourceThread }) })\n\tVERBOSE.isDisabled || autorun(() => VERBOSE(`[queryDivergencesByPrev] result:`, toJS(divergences)))\n\treturn divergences\n}, { equals: comparer.structural })\n\n// export const queryDivergencesOfEnAtByPrev = computedFnDeepCompare('queryDivergencesOfEnAtByPrev', function queryDivergencesOfEnAtByPrev(\n// \tsourceThread: Thread,\n// ) {\n// \tDEBUG(`queryDivergencesOfEnAtByPrev<${sourceThread.nameAndSizeUntracked}>`)\n// \tif (sourceThread.filters.includes('lastWriteWins')) WARN(`queryDivergencesOfEnAtByPrevFon thread lastWriteWins`, sourceThread)\n\n// \tconst divergences = observableArrayMap(() => {\n// \t\tconst logsForNode = new Map<CidString, Applog[]>()\n// \t\tconst leafs = new Map<string, Set<CidString>>() // [en,at]\n// \t\tVERBOSE('all applogs:', sourceThread.applogs)\n// \t\tfor (const log of sourceThread.applogs) {\n// \t\t\tconst key = stringify([log.en, log.at])\n// \t\t\tif (!leafs.has(key)) leafs.set(key, new Set())\n// \t\t\tlet prevLogs\n// \t\t\tif (log.pv) {\n// \t\t\t\tprevLogs = log.pv && logsForNode.get(log.pv.toString())\n// \t\t\t\tleafs.get(key).delete(log.pv.toString())\n// \t\t\t}\n// \t\t\tVERBOSE('traversing log', { key, log, prevLogs, leafs: Array.from(leafs) })\n// \t\t\tlogsForNode.set(log.cid, prevLogs ? [...prevLogs, log] : [log])\n// \t\t\tleafs.get(key).add(log.cid)\n// \t\t}\n// \t\treturn Array.from(leafs.entries()).map(([_enAt, leafs]) => {\n// \t\t\t// TODO use MappedThread?\n// \t\t\tconst thread = new ThreadInMemory(\n// \t\t\t\tcreateDebugName({\n// \t\t\t\t\tcaller: 'DivergenceLeaf',\n// \t\t\t\t\tthread: sourceThread,\n// \t\t\t\t\tpattern: `leaf: ${leafID}`,\n// \t\t\t\t}),\n// \t\t\t\tlogsForNode.get(leafID),\n// \t\t\t\tsourceThread.filters,\n// \t\t\t\ttrue,\n// \t\t\t\t// TODO: sourceThread,\n// \t\t\t)\n// \t\t\treturn ({ log: thread.latestLog, thread })\n// \t\t})\n// \t}, { name: createDebugName({ caller: 'queryDivergencesOfEnAtByPrev', thread: sourceThread }) })\n// \tVERBOSE.isDisabled || autorun(() => VERBOSE(`[queryDivergencesOfEnAtByPrev] result:`, toJS(divergences)))\n// \treturn divergences\n// }, { equals: comparer.structural })\n","import { DatomPart } from '../applog/datom-types'\n\nexport function includes(str: string) {\n\treturn (vl: DatomPart) => vl?.includes?.(str)\n}\nexport function includedIn(arr: string[]) {\n\treturn (vl: DatomPart) => arr?.includes?.(vl)\n}\n","import { computed, makeObservable, untracked } from 'mobx'\nimport { joinThreads } from '../applog/applog-helpers'\nimport { SearchContext } from '../applog/datom-types'\nimport { observableArrayMap } from '../mobx/mobx-utils'\nimport type { Thread } from '../thread/basic'\nimport { ReadonlyObservableArray } from '../types/typescript-utils'\n\nexport class QueryNode {\n\tconstructor(\n\t\treadonly logsOfThisNode: Thread,\n\t\treadonly variables: SearchContext,\n\t\treadonly prevNode: QueryNode | null = null,\n\t) {\n\t\tmakeObservable(this, {\n\t\t\tthreadOfTrail: computed, // ? intuitively only put the ones here that felt expensive to compute (join)\n\t\t})\n\t}\n\tget record() {\n\t\treturn this.variables // alias for end-user consumption\n\t}\n\n\tget threadOfTrail() {\n\t\tif (!this.prevNode) return this.logsOfThisNode\n\t\treturn joinThreads([\n\t\t\tthis.logsOfThisNode,\n\t\t\tthis.prevNode.threadOfTrail,\n\t\t])\n\t}\n\tget trailLogs() {\n\t\treturn this.threadOfTrail.applogs\n\t}\n}\n/**\n * The result of a query (-step)\n */\nexport class QueryResult {\n\tconstructor(\n\t\tpublic nodes: ReadonlyObservableArray<QueryNode>,\n\t) {\n\t\tmakeObservable(this, {\n\t\t\tthreadOfAllTrails: computed, // ? intuitively only put the ones here that felt expensive to compute (join)\n\t\t\tsize: computed, // ... or cheap to cache\n\t\t\tisEmpty: computed,\n\t\t})\n\t}\n\n\tget size() {\n\t\treturn this.records.length\n\t}\n\tget isEmpty() {\n\t\treturn this.records.length === 0\n\t}\n\tget untrackedSize() {\n\t\treturn untracked(() => this.records.length)\n\t}\n\n\tget records() {\n\t\treturn observableArrayMap(() => this.nodes.map(({ variables }) => variables), { name: 'QueryResult.records' })\n\t}\n\tget leafNodeThread() {\n\t\treturn joinThreads(\n\t\t\tobservableArrayMap(() => this.nodes.map(({ logsOfThisNode: thread }) => thread), { name: 'QueryResult.leafNodeThread' }),\n\t\t)\n\t}\n\tget leafNodeLogSet() {\n\t\treturn observableArrayMap(() => this.nodes.map(({ logsOfThisNode: thread }) => thread.applogs), { name: 'QueryResult.leafNodeLogSet' })\n\t}\n\tget leafNodeLogs() {\n\t\treturn observableArrayMap(() => this.nodes.flatMap(({ logsOfThisNode: thread }) => thread.applogs), {\n\t\t\tname: 'QueryResult.leafNodeLogs',\n\t\t})\n\t}\n\t// get trailThreads() {\n\t// \treturn observableArrayMap(() => this.nodes.map(({ trailThread }) => trailThread))\n\t// }\n\tget threadOfAllTrails() {\n\t\treturn joinThreads(observableArrayMap(() => this.nodes.map(node => node.threadOfTrail), { name: 'QueryResult.threadOfAllTrails' }))\n\t}\n\tget thread() {\n\t\treturn this.threadOfAllTrails // alias\n\t}\n\tget allApplogs() {\n\t\treturn this.threadOfAllTrails.applogs // mostly for easy logging\n\t}\n}\n","import { AgentHash, Applog, ApplogValue, DatalogQueryPattern, EntityID, SearchContext, ValueOrMatcher } from '../applog/datom-types'\n\nimport { Logger } from 'besonders-logger'\nimport { action, autorun, comparer, computed, makeObservable, observable, onBecomeObserved, toJS, untracked } from 'mobx'\n\nimport { isEmpty } from 'lodash-es'\nimport stringify from 'safe-stable-stringify'\nimport { resolveOrRemoveVariables, sortApplogsByTs } from '../applog/applog-utils'\nimport {\n\tapplogThreadComparer,\n\tcomputedFnDeepCompare,\n\tcomputedStructuralComparer,\n\tcreateDebugName,\n\tobservableArrayMap,\n\tobservableSetMap,\n\tqueryNodesComparer,\n} from '../mobx/mobx-utils'\nimport { isInitEvent, StaticThread, Thread, ThreadEvent } from '../thread/basic'\nimport { rollingFilter, rollingMapper, ThreadOnlyCurrent } from '../thread/filters'\nimport { MappedThread } from '../thread/mapped'\nimport { ThreadInMemory } from '../thread/writeable'\nimport { QueryNode, QueryResult } from './types'\n\nconst { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO, { prefix: '[q]' }) // eslint-disable-line no-unused-vars\n\nlet globalQueryTimeoutTime = null\n\n// util.inspect.defaultOptions.depth = 5;\n\n// export interface QueryExecutorArguments {\n// db: Thread\n// // applogs: AppLog[]\n// nodes: SearchContextWithLog[]\n// }\n// export interface QueryExecutorResult {\n// // applogs: AppLog[]\n// nodes: SearchContextWithLog[]\n// }\n// export type QueryExecutor = (args: QueryExecutorArguments) => QueryExecutorResult\n\n/////////////\n// QUERIES //\n/////////////\n\n/**\n * Keep only the latest logs for each en&at (= last write wins)\n */\nexport const lastWriteWins = computedFnDeepCompare('lastWriteWins', function lastWriteWins(\n\tthread: Thread,\n\t{ inverseToOnlyReturnFirstLogs, tolerateAlreadyFiltered }: {\n\t\tinverseToOnlyReturnFirstLogs?: boolean\n\t\ttolerateAlreadyFiltered?: boolean\n\t} = {},\n): ThreadOnlyCurrent {\n\tVERBOSE(`lastWriteWins${inverseToOnlyReturnFirstLogs ? '.inversed' : ''} < ${thread.nameAndSizeUntracked} > initializing`)\n\t// if (thread.name.includes('lastWriteWins')) WARN(`thread already contains lastWriteWins:`, thread.name)\n\tif (thread.filters.includes('lastWriteWins')) {\n\t\tif (tolerateAlreadyFiltered) {\n\t\t\tDEBUG(`[lastWriteWins] already filtered, but tolerateAlreadyFiltered=true, so returning`)\n\t\t\treturn thread as ThreadOnlyCurrent\n\t\t}\n\t\tthrow ERROR(`thread already filtered lastWriteWins:`, thread.filters, { name: thread.name })\n\t}\n\n\tlet rollingMap: Map<string, Applog>\n\tconst mappedThread = rollingMapper(thread, function lastWriteWinsMapper(event, sourceThread) {\n\t\tconst isInitial = isInitEvent(event)\n\n\t\tlet newLogs: readonly Applog[]\n\t\tconst toAdd = [] as Applog[]\n\t\tconst toRemove = isInitial ? null : [] as Applog[]\n\t\tif (isInitial) {\n\t\t\trollingMap = new Map()\n\t\t\tnewLogs = event.init\n\t\t} else {\n\t\t\tnewLogs = event.added\n\t\t}\n\n\t\tlet tsCheck: string\n\t\tfor (\n\t\t\tlet i = inverseToOnlyReturnFirstLogs ? 0 : newLogs.length - 1;\n\t\t\tinverseToOnlyReturnFirstLogs ? i < newLogs.length : i >= 0;\n\t\t\tinverseToOnlyReturnFirstLogs ? i++ : i--\n\t\t) {\n\t\t\tconst log = newLogs[i]\n\t\t\tconst key = log.en + '|' + log.at // stringify([log.en, log.at]) - less efficient\n\n\t\t\t// TODO: use isoDateStrCompare ?\n\t\t\tif (tsCheck && (inverseToOnlyReturnFirstLogs ? tsCheck > log.ts : tsCheck < log.ts)) {\n\t\t\t\tthrow ERROR(`lastWriteWins.mapper logs not sorted:`, tsCheck, inverseToOnlyReturnFirstLogs ? '>' : '<', log.ts, {\n\t\t\t\t\tlog,\n\t\t\t\t\ti,\n\t\t\t\t\tnewLogs,\n\t\t\t\t\tinverseToOnlyReturnFirstLogs,\n\t\t\t\t})\n\t\t\t}\n\t\t\ttsCheck = log.ts\n\n\t\t\tconst existing = rollingMap.get(key)\n\t\t\tif (!existing || (inverseToOnlyReturnFirstLogs ? (existing.ts > log.ts) : (existing.ts < log.ts))) {\n\t\t\t\tif (existing && !isInitial) toRemove.push(existing)\n\t\t\t\ttoAdd.push(log)\n\t\t\t\trollingMap.set(key, log)\n\t\t\t}\n\t\t}\n\t\tsortApplogsByTs(toAdd) // HACK: find logical solution\n\t\tVERBOSE.isDisabled ||\n\t\t\tVERBOSE(\n\t\t\t\t`lastWriteWins${inverseToOnlyReturnFirstLogs ? '.inversed' : ''}<${thread.nameAndSizeUntracked}> mapped event`,\n\t\t\t\tisInitial ?\n\t\t\t\t\t{ ...Object.fromEntries(Object.entries(event).map(([k, v]) => [k, v?.length])), toAdd: toAdd.length, toRemove } :\n\t\t\t\t\t{ ...event, toAdd, toRemove },\n\t\t\t)\n\t\treturn isInitial ?\n\t\t\t{ init: toAdd }\n\t\t\t: { added: toAdd, removed: toRemove }\n\t}, { name: `lastWriteWins${inverseToOnlyReturnFirstLogs ? '.inversed' : ''}`, extraFilterName: 'lastWriteWins' })\n\tVERBOSE.isDisabled || autorun(() => {\n\t\tVERBOSE(`lastWriteWins<${thread.nameAndSizeUntracked}> filtered down to`, mappedThread.applogs.length) // using applogs.length, as size might not change, but we still want a log\n\t})\n\treturn mappedThread as ThreadOnlyCurrent\n\t// const filtered = observableArrayMap(() => {\n\t// VERBOSE(`lastWriteWins thread deps:`, getDependencyTree(thread.applogs), thread)\n\t// thread.applogs.forEach(applog => {\n\t// const key = stringify([applog.en, applog.at])\n\t// const existing = mapped.get(key)\n\t// if (!existing || existing.ts < applog.ts)\n\t// mapped.set(key, applog)\n\t// })\n\t// VERBOSE(`[lastWriteWins] mapped:`, mapped.size)\n\t// return Array.from(mapped.values())\n\t// }, { name: obsArrMapName })\n\t// VERBOSE(`lastWriteWins deps of filteredArr:`, getDependencyTree(filtered))\n\t// return new MappedThread(thread, filtered, `${thread.name} | lastWriteWins`)\n}, { equals: applogThreadComparer, argsDebugName: (thread) => createDebugName({ caller: 'lastWriteWins', thread }) })\n\n/**\n * Remove all applogs for entities that have an applog: { at: `isDeleted`, val: true }\n * ! WARNING: If not based on lastWriteWins, it will not respect un-deletions yet (isDeleted: false)\n */\nexport const withoutDeleted = computedFnDeepCompare('withoutDeleted', function withoutDeleted(\n\tthread: Thread,\n) {\n\tif (VERBOSE.isEnabled) VERBOSE(`withoutDeleted<${thread.nameAndSizeUntracked}>`)\n\t// if (thread.name.includes('withoutDeleted')) WARN(`thread already contains withoutDeleted:`, withoutDeleted)\n\tif (thread.filters.includes('withoutDeleted')) {\n\t\tthrow ERROR(`thread already filtered withoutDeleted:`, thread.filters, { name: thread.name })\n\t}\n\n\tconst deletionLogs = rollingFilter(\n\t\tthread, // TODO: handle un-delection\n\t\t{ at: ['isDeleted', 'relation/isDeleted', 'block/isDeleted'], vl: true },\n\t\t{ name: 'isDeleted' },\n\t)\n\tVERBOSE.isEnabled &&\n\t\tVERBOSE(\n\t\t\t`withoutDeleted<${thread.nameAndSizeUntracked}> deletionLogs:`,\n\t\t\tuntracked(function expensiveAssUntrackedVerboseFx() {\n\t\t\t\treturn [...deletionLogs.applogs]\n\t\t\t}),\n\t\t)\n\tconst obsArrMapName = createDebugName({ caller: 'allDeletedEntities', thread })\n\tconst deleted = observableSetMap(function observableSetMapForDeleted() {\n\t\treturn deletionLogs.map(log => log.en)\n\t}, { name: obsArrMapName })\n\t// if (VERBOSE.isEnabled) VERBOSE(`withoutDeleted<${db.nameAndSize}> deleted:`, untracked(() => [...deleted]))\n\tif (VERBOSE.isEnabled) {\n\t\tautorun(() => {\n\t\t\tVERBOSE(`withoutDeleted<${thread.nameAndSizeUntracked}> deleted:`, [...deleted])\n\t\t})\n\t}\n\n\treturn rollingFilter(thread, { '!en': deleted }, { name: `withoutDeleted`, extraFilterName: 'withoutDeleted' })\n}, { equals: applogThreadComparer })\n\n// export const filterStatic = computedFnDeepCompare('filterStatic', function filterStatic(\n// thread: Thread,\n// pattern: DatalogQueryPattern,\n// opts: { name?: string } = {},\n// ) {\n// VERBOSE(`filterStatic<${thread.nameAndSizeUntracked}>:`, pattern)\n// if (!Object.entries(pattern).length) throw new Error(`Pattern is empty`)\n// //TODO: deprecaate in favor of rollingFilter ?\n// return new Thread(thread, thread.applogs.filter(applog => {\n// for (const [field, patternValue] of Object.entries(pattern)) {\n// const applogValue = applog[field.startsWith('!') ? field.slice(1) : field]\n// if (!matchPartStatic(field, patternValue, applogValue))\n// return false\n// }\n// return true\n// }), `${thread.name} | ${opts.name || `filterStatic{${stringify(pattern)}}`}`)\n// }, { equals: applogThreadComparer })\n\nexport const query = computedFnDeepCompare('query', function query(\n\tthreadOrLogs: Thread | Applog[],\n\tpatternOrPatterns: DatalogQueryPattern | DatalogQueryPattern[],\n\tstartVariables: SearchContext = {},\n\topts: { debug?: boolean } = {},\n) {\n\tthrowOnTimeout()\n\tconst thread = threadFromMaybeArray(threadOrLogs)\n\tDEBUG(`query<${thread.nameAndSizeUntracked}>:`, patternOrPatterns)\n\tconst patterns = (Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns]) as DatalogQueryPattern[]\n\n\tlet nodes: QueryResult | null\n\tif (patterns.length === 1) {\n\t\t// We are the first step, so start from scratch\n\t\tnodes = null\n\t} else {\n\t\t// Run the previous step(s) first (= recursion)\n\t\tconst pattersExceptLast = patterns.slice(0, -1)\n\t\t// recursively call this function to have partial queries cacheable\n\t\tnodes = query(thread, pattersExceptLast, startVariables, opts)\n\t}\n\tconst lastPattern = patterns[patterns.length - 1]\n\tconst stepResult = queryStep(thread, nodes, lastPattern, opts)\n\tVERBOSE.isDisabled || autorun(() => VERBOSE(`query result:`, toJS(stepResult)))\n\treturn stepResult\n}, {\n\tequals: queryNodesComparer,\n\targsDebugName: (thread, pattern, startVars) =>\n\t\tcreateDebugName({ caller: 'query', thread, args: startVars ? { pattern, startVars } : pattern }),\n})\n\nexport const queryStep = computedFnDeepCompare('queryStep', function queryStep(\n\tthread: Thread,\n\tnodeSet: QueryResult | null,\n\tpattern: DatalogQueryPattern,\n\t// variables: SearchContext = {},\n\topts: { debug?: boolean } = {},\n) {\n\tDEBUG(`queryStep<${thread.nameAndSizeUntracked}> with`, nodeSet?.untrackedSize ?? 'all', 'nodes, pattern:', pattern)\n\tif (!Object.entries(pattern).length) throw new Error(`Pattern is empty`)\n\n\tfunction doQuery(node: QueryNode | null) {\n\t\tconst [patternWithResolvedVars, variablesToFill] = resolveOrRemoveVariables(pattern, node?.variables ?? {})\n\t\tVERBOSE(`[queryStep.doQuery] patternWithoutVars: `, patternWithResolvedVars)\n\t\tconst applogsMatchingStatic = rollingFilter(thread, patternWithResolvedVars)\n\t\tconst varMapper = createObjMapper(variablesToFill)\n\t\tconst resultNodes = observableArrayMap(function queryStepDoStep() {\n\t\t\tconst newVarsAndTheirLog = applogsMatchingStatic.map(log => ({ log, vars: varMapper(log) }))\n\t\t\tif (VERBOSE.isEnabled) {\n\t\t\t\tVERBOSE(\n\t\t\t\t\t`[queryStep.doQuery] step node:`,\n\t\t\t\t\tnode?.variables,\n\t\t\t\t\t' =>',\n\t\t\t\t\tnewVarsAndTheirLog,\n\t\t\t\t\t'from:',\n\t\t\t\t\tuntracked(() => applogsMatchingStatic.applogs),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\treturn newVarsAndTheirLog.map(({ log, vars }) => {\n\t\t\t\tconst nodeVars = Object.assign({}, node?.variables, vars)\n\t\t\t\treturn new QueryNode(\n\t\t\t\t\t// TODO: ? Make single result nodes reactive using MappedThread - only really relevant if a result had multiple logs (or different paths would lead to the same result?)\n\t\t\t\t\t// ThreadInMemory.fromArray(\n\t\t\t\t\tStaticThread.fromArray(\n\t\t\t\t\t\t[log],\n\t\t\t\t\t\tcreateDebugName({\n\t\t\t\t\t\t\tcaller: 'QueryNode',\n\t\t\t\t\t\t\tthread: applogsMatchingStatic,\n\t\t\t\t\t\t\tpattern: `${stringify(nodeVars)}@${stringify(patternWithResolvedVars)}`,\n\t\t\t\t\t\t}),\n\t\t\t\t\t\t// true,\n\t\t\t\t\t),\n\t\t\t\t\tnodeVars,\n\t\t\t\t\tnode,\n\t\t\t\t)\n\t\t\t})\n\t\t}, { name: createDebugName({ caller: 'doQuery.mapNodes', thread: applogsMatchingStatic, pattern }) })\n\t\tif (VERBOSE.isEnabled) autorun(() => VERBOSE(`[queryStep.doQuery] resultNodes:`, [...resultNodes]))\n\t\tif (opts.debug) {\n\t\t\tLOG(\n\t\t\t\t`[queryStep] step result:`,\n\t\t\t\tuntracked(() =>\n\t\t\t\t\tresultNodes.map(({ variables, logsOfThisNode: thread }) => ({\n\t\t\t\t\t\tvariables,\n\t\t\t\t\t\tthread, // : /* util.inspect( */ thread.applogs, /* , { showHidden: false, depth: null }) */\n\t\t\t\t\t}))\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t\treturn resultNodes\n\t}\n\tconst observableResultNodes = observableArrayMap(\n\t\tfunction queryStepGetResults() {\n\t\t\tDEBUG(`[queryStep] Running with ${nodeSet?.nodes?.length} input nodes:`)\n\t\t\tif (!nodeSet) {\n\t\t\t\t// first query step\n\t\t\t\treturn [...doQuery(null)] // HACK copy array bc otherwise the observableArrayMap doesn't seem to depend on the contents somehow\n\t\t\t} else {\n\t\t\t\t// subsequent query steps\n\t\t\t\treturn [...nodeSet.nodes.flatMap(doQuery)]\n\t\t\t}\n\t\t},\n\t\t{ name: createDebugName({ caller: 'queryStep', thread, pattern }) },\n\t)\n\n\tif (VERBOSE.isEnabled) autorun(() => VERBOSE(`[queryStep] observableResultNodes:`, [...observableResultNodes]))\n\treturn new QueryResult(observableResultNodes)\n}, { equals: queryNodesComparer, argsDebugName: (thread, _nodes, pattern) => createDebugName({ caller: 'queryStep', thread, pattern }) })\n\nexport const queryNot = computedFnDeepCompare('queryNot', function queryNot( // TODO: update old-style query\n\tthread: Thread,\n\tstartNodes: QueryResult,\n\tpatternOrPatterns: DatalogQueryPattern | DatalogQueryPattern[],\n\topts: { debug?: boolean } = {},\n) {\n\tlet nodes = startNodes.nodes\n\tDEBUG(`queryNot<${thread.nameAndSizeUntracked}> from: ${nodes.length} nodes`)\n\tconst patterns = (Array.isArray(patternOrPatterns) ? patternOrPatterns : [patternOrPatterns]) as DatalogQueryPattern[]\n\n\tfor (const pattern of patterns) {\n\t\tif (!Object.entries(patternOrPatterns).length) throw new Error(`Pattern is empty`)\n\t\tnodes = nodes.filter(function innerNodeFilter({ /* applogs, */ variables }) {\n\t\t\tconst [patternWithResolvedVars, _variablesToFill] = resolveOrRemoveVariables(pattern, variables ?? {})\n\t\t\tVERBOSE(`[queryNot] patternWithoutVars: `, patternWithResolvedVars)\n\t\t\tconst newApplogs = rollingFilter(thread, patternWithResolvedVars)\n\t\t\tVERBOSE(`[queryNot] step node:`, variables, ' =>', newApplogs.size, 'applogs')\n\t\t\tVERBOSE.isDisabled || VERBOSE(`[queryNot] step node:`, variables, ' => empty?', untracked(() => newApplogs.applogs))\n\n\t\t\tif (opts.debug) LOG(`[queryNot] node result:`, variables, '=>', newApplogs.applogs)\n\t\t\treturn newApplogs.isEmpty\n\t\t})\n\t}\n\treturn new QueryResult(nodes)\n}, { equals: queryNodesComparer, argsDebugName: (thread, nodes, pattern) => createDebugName({ caller: 'queryNot', thread, pattern }) })\n\n// export function or(queries: QueryExecutor[]) {\n// return tagged(\n// `or{${stringify(queries)} } `,\n// function orExecutor(args: QueryExecutorArguments) {\n// const { db, nodes: contexts } = args\n// VERBOSE('[or]', { queries, contexts })\n// let results = []\n// for (const query of queries) {\n// const res = query(args)\n// VERBOSE('[or] query', query, 'result =>', res)\n// results.push(...res.nodes)\n// }\n// return { contexts: results }\n// }\n// )\n// }\n\n// export type Tagged<T> = T & { tag: string }\n// export function tagged<T>(tag: string, thing: T): Tagged<T> {\n// const e = thing as (T & { tag: string })\n// e.tag = tag\n// return e\n// }\n\n//////////////////////\n// COMPOSED QUERIES //\n//////////////////////\n// createDebugName({ caller: 'useKidRelations' }, true)\nexport const filterAndMap = computedFnDeepCompare('filterAndMap', function filterAndMap<R>(\n\tthread: Thread,\n\tpattern: DatalogQueryPattern,\n\tmapper: (keyof Applog) | (Partial<{ [key in keyof Applog]: string }>) | ((applog: Applog) => R),\n) {\n\tDEBUG(`filterAndMap<${thread.nameAndSizeUntracked}>`, pattern)\n\n\tconst filtered = rollingFilter(thread, pattern)\n\tif (VERBOSE.isEnabled) {\n\t\tVERBOSE(`[filterAndMap] filtered:`, filtered.untrackedSize)\n\t\tautorun(() => VERBOSE(`[filterAndMap] filtered:`, filtered.applogs))\n\t}\n\n\tconst name = createDebugName({ thread, pattern, caller: 'filterAndMap' })\n\tconst mapped = observableArrayMap<ApplogValue | any>(() => mapThreadWith(filtered, mapper), { name }) // TODO typing:? Record<string, ApplogValue> ?\n\tVERBOSE.isDisabled || autorun(() => VERBOSE(`[filterAndMap] mapped:`, mapped))\n\treturn mapped\n}, { equals: comparer.structural, argsDebugName: (thread, pattern) => createDebugName({ caller: 'filterAndMap', thread, pattern }) })\n\nexport const queryAndMap = computedFnDeepCompare('queryAndMap', function queryAndMap<R>(\n\tthreadOrLogs: Thread | Applog[],\n\tpatternOrPatterns: Parameters<typeof query>[1],\n\tmapDef: string | (Partial<{ [key in keyof SearchContext]: string }>) | ((record: SearchContext) => R),\n\tvariables: SearchContext = {},\n) {\n\tconst thread = threadFromMaybeArray(threadOrLogs)\n\tDEBUG(`queryAndMap<${thread.nameAndSizeUntracked}>`, { patternOrPatterns, variables, map: mapDef })\n\tconst debugName = createDebugName({ thread, caller: 'queryAndMap' })\n\n\tconst queryResult = query(thread, patternOrPatterns)\n\tVERBOSE(`[queryAndMap] filtered count:`, queryResult.untrackedSize)\n\tconst mapped = observableArrayMap<ApplogValue | any>(\n\t\t() => mapQueryResultWith(queryResult, mapDef),\n\t\t{ name: debugName },\n\t)\n\tVERBOSE.isDisabled || autorun(() => VERBOSE(`[queryAndMap] result:`, toJS(mapped)))\n\treturn mapped\n}, { equals: comparer.structural, argsDebugName: (thread, pattern) => createDebugName({ caller: 'queryAndMap', thread, pattern }) })\n\nexport const queryEntity = computedFnDeepCompare('queryEntity', function queryEntity(\n\tthread: Thread,\n\tname: string,\n\tentityID: EntityID,\n\tattributes: readonly string[],\n) {\n\tDEBUG(`queryEntity<${thread.nameAndSizeUntracked}>`, entityID, name)\n\n\tconst filtered = rollingFilter(thread, { en: entityID, at: prefixAttrs(name, attributes) })\n\tVERBOSE(`queryEntity applogs:`, filtered.applogs)\n\treturn computed(() =>\n\t\tfiltered.isEmpty ? null : Object.fromEntries(\n\t\t\tfiltered.map(({ at, vl }) => [at.slice(name.length + 1), vl]),\n\t\t)\n\t)\n}, {\n\tequals: computedStructuralComparer,\n\targsDebugName: (thread, name, entityID) => createDebugName({ caller: 'queryEntity', thread, args: { name, entityID } }),\n})\n\nexport const agentsOfThread = computedFnDeepCompare('agentsOfThread', function agentsOfThread(\n\tthread: Thread,\n) {\n\tDEBUG(`agentsOfThread<${thread.nameAndSizeUntracked}>`)\n\n\tconst mapped = observable.map<string, number>()\n\tconst onEvent = action((event: ThreadEvent) => {\n\t\tfor (const log of (isInitEvent(event) ? event.init : event.added)) {\n\t\t\tconst prev = mapped.get(log.ag) ?? 0\n\t\t\tmapped.set(log.ag, prev + 1)\n\t\t}\n\t\tfor (const log of (!isInitEvent(event) && event.removed || [])) {\n\t\t\tconst prev = mapped.get(log.ag)\n\t\t\tif (!prev || prev < 1) throw ERROR(`[agentsOfThread] number is now negative`, { log, event, mapped, prev })\n\t\t\tmapped.set(log.ag, prev - 1)\n\t\t}\n\t\tLOG(`agentsOfThread<${thread.nameAndSizeUntracked}> processed event`, { event, mapped })\n\t})\n\n\tonEvent({ init: thread.applogs })\n\tconst unsubscribe = thread.subscribe(onEvent)\n\tonBecomeObserved(mapped, unsubscribe)\n\n\treturn mapped\n})\n\nexport const entityOverlap = computedFnDeepCompare('entityOverlap', function entityOverlapCount(\n\tthreadA: Thread,\n\tthreadB: Thread,\n) {\n\tLOG(`entityOverlap<${threadA.nameAndSizeUntracked}, ${threadB.nameAndSizeUntracked}>`)\n\n\treturn computed(() => {\n\t\tconst entitiesA = new Set(threadA.map(log => log.en))\n\t\tconst entitiesB = new Set(threadB.map(log => log.en))\n\t\treturn [...entitiesA].filter(en => entitiesB.has(en))\n\t})\n})\n\nexport const entityOverlapMap = function entityOverlapMap(\n\tthreadA: Thread,\n\tthreadB: Thread,\n\tthreadAName = 'incoming',\n\tthreadBName = 'current',\n) {\n\tconst useInferredVM = (en, thread: Thread) => en\n\tconst overlapping = entityOverlap(threadA, threadB).get()\n\tconst mapped = new Map()\n\toverlapping.forEach(eachEntityID => (\n\t\tmapped.set(eachEntityID, {\n\t\t\t[threadAName]: useInferredVM(eachEntityID, threadA),\n\t\t\t[threadBName]: useInferredVM(eachEntityID, threadB),\n\t\t})\n\t))\n}\n\nexport const entityOverlapCount = computedFnDeepCompare(\n\t'entityOverlapCount',\n\tfunction entityOverlapCount(threadA: Thread, threadB: Thread) {\n\t\treturn computed(() => entityOverlap(threadA, threadB).get().length)\n\t},\n)\nexport const querySingle = computedFnDeepCompare('querySingle', function querySingle(\n\tthreadOrLogs: Thread | Applog[],\n\tpatternOrPatterns: Parameters<typeof query>[1],\n\tvariables: SearchContext = {},\n) {\n\tconst result = query(threadOrLogs, patternOrPatterns, variables)\n\treturn computed(() => {\n\t\tif (result.isEmpty) return null\n\t\tif (result.size > 1) throw ERROR(`[querySingle] got`, result.size, `results:`, result)\n\t\tconst logsOfThisNode = result.nodes[0].logsOfThisNode\n\t\tif (logsOfThisNode.size != 1) throw ERROR(`[querySingle] single result, but got`, logsOfThisNode.size, `logs:`, logsOfThisNode.applogs)\n\t\treturn logsOfThisNode.applogs[0]\n\t})\n}, {\n\tequals: comparer.structural,\n\targsDebugName: (thread, pattern) => createDebugName({ caller: 'querySingle', thread, pattern }),\n})\n\nexport const querySingleAndMap = computedFnDeepCompare(\n\t'querySingleAndMap',\n\tfunction querySingleAndMap<MAP extends (keyof Applog | (Partial<{ [key in keyof Applog]: string }>))>(\n\t\tthreadOrLogs: Thread | Applog[],\n\t\tpatternOrPatterns: Parameters<typeof query>[1],\n\t\tmapDef: MAP,\n\t\tvariables: SearchContext = {},\n\t) {\n\t\tconst resultBox = querySingle(threadOrLogs, patternOrPatterns, variables)\n\t\treturn computed<ApplogValue | { [key in keyof MAP]: ApplogValue } | null>(() => {\n\t\t\tconst log = resultBox.get()\n\t\t\tif (!log) return undefined\n\t\t\tif (typeof mapDef === 'string') {\n\t\t\t\treturn log[mapDef as string]\n\t\t\t} else {\n\t\t\t\treturn createObjMapper(mapDef)(log)\n\t\t\t}\n\t\t})\n\t},\n\t{\n\t\tequals: comparer.structural,\n\t\targsDebugName: (thread, pattern) => createDebugName({ caller: 'querySingleAndMap', thread, pattern }),\n\t},\n)\n/////////////\n// HELPERS //\n/////////////\n\nexport const mapThreadWith = function filterAndMapGetterFx<R>(\n\tthread: Thread,\n\tmapDef: (keyof Applog) | (Partial<{ [key in keyof Applog]: string }>) | ((applog: Applog) => R),\n) {\n\tif (typeof mapDef === 'function') {\n\t\treturn thread.map(mapDef)\n\t} else if (typeof mapDef === 'string') {\n\t\treturn thread.map(log => log[mapDef])\n\t} else {\n\t\treturn thread.map(createObjMapper(mapDef))\n\t}\n}\nexport const mapQueryResultWith = function filterAndMapGetterFx<R>(\n\tqueryResult: QueryResult,\n\tmapDef: string | (Partial<{ [key in keyof SearchContext]: string }>) | ((record: SearchContext) => R),\n) {\n\tif (typeof mapDef === 'function') {\n\t\treturn queryResult.records.map(mapDef)\n\t} else if (typeof mapDef === 'string') {\n\t\treturn queryResult.nodes.map((node) => {\n\t\t\tif (!Object.hasOwn(node.record, mapDef)) {\n\t\t\t\tif (node.logsOfThisNode.size !== 1) {\n\t\t\t\t\tthrow ERROR(`not sure what to map (it's not a var and a result node log count of ${node.logsOfThisNode.size})`)\n\t\t\t\t}\n\t\t\t\treturn node.logsOfThisNode.firstLog[mapDef]\n\t\t\t}\n\t\t\treturn node.record[mapDef]\n\t\t})\n\t} else {\n\t\treturn queryResult.nodes.map((node) => {\n\t\t\treturn createObjMapper(mapDef)(queryResult)\n\t\t})\n\t}\n}\n/**\n * Map Applog to custom named record, e.g.:\n * { en: 'movieID', vl: 'movieName' }\n * will map the applog to { movieID: .., movieName: .. }\n */\nexport function createObjMapper<FROM extends string, TO extends string>(applogFieldMap: Partial<{ [key in FROM]: TO }>) {\n\treturn (applog: { [key in FROM]: any }) => {\n\t\treturn Object.entries(applogFieldMap).reduce((acc, [key, value]) => {\n\t\t\tacc[value as TO] = applog[key]\n\t\t\treturn acc\n\t\t}, {} as Partial<{ [key in TO]: ApplogValue }>)\n\t}\n}\n\nexport function startsWith(str: string) {\n\treturn (value) => value.startsWith(str)\n}\n\nexport function prefixAttrs(prefix: string, attrs: readonly string[]) {\n\treturn attrs.map(at => prefixAt(prefix, at))\n}\nexport function prefixAt(prefix: string, attr: string) {\n\treturn `${prefix}/${attr}`\n}\nexport function threadFromMaybeArray(threadOrLogs: Thread | Applog[], name?: string) {\n\tif (!Array.isArray(threadOrLogs)) {\n\t\treturn threadOrLogs\n\t}\n\treturn ThreadInMemory.fromArray(threadOrLogs, name || `threadFromArray[${threadOrLogs.length}]`, true)\n}\nexport function withTimeout<R>(timeoutMilliseconds: number, func: () => R) {\n\tif (globalQueryTimeoutTime) throw ERROR(`Nested timeout not supported`)\n\tglobalQueryTimeoutTime = performance.now() + timeoutMilliseconds\n\tconst result = func()\n\n\tglobalQueryTimeoutTime = null\n\treturn result\n}\nexport function throwOnTimeout() {\n\tif (globalQueryTimeoutTime == null) return\n\tif (performance.now() >= globalQueryTimeoutTime) {\n\t\tthrow new QueryTimeoutError(globalQueryTimeoutTime)\n\t}\n}\nclass QueryTimeoutError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message)\n\t}\n}\n","import type { Applog, EntityID } from '@wovin/core/applog'\nimport type { ThreadOnlyCurrentNoDeleted } from '@wovin/core/thread'\nimport { query } from '@wovin/core/query'\n\n/**\n * Generic recursive traversal utility for note tree structures.\n *\n * Traverses a note and all its descendants, applying a mapping function to each\n * node and combining results using a join function.\n *\n * @param thread - Pre-filtered thread (from `lastWriteWins(withoutDeleted(raw))`)\n * @param blockID - The root block ID to start traversal from\n * @param mapKid - Function to apply to each block/relation pair\n * @param joinResults - Function to combine parent result with children results\n * @returns The combined result of the traversal\n *\n * @throws Error if circular references are detected or depth exceeds 42 levels\n *\n * @internal Used by collectSubtreeApplogs; not typically used directly\n */\nexport function mapAndRecurseKids<R = void>(\n\tthread: ThreadOnlyCurrentNoDeleted,\n\tblockID: EntityID,\n\tmapKid: (kid: { relID: EntityID | null, blockID: EntityID }) => R,\n\tjoinResults: (blockResult: R, kidResults: R[]) => R,\n) {\n\tconst recurse = function recurseOuter(blockID: EntityID, relID: EntityID | null, trace: EntityID[]) {\n\t\t// Recursion checks\n\t\tif (trace.includes(blockID)) {\n\t\t\tthrow new Error(`[mapAndRecurseKids.loop] Circular reference detected: ${blockID}`)\n\t\t}\n\t\tif (trace.length > 42) {\n\t\t\tthrow new Error(`[mapAndRecurseKids.maxDepth] Maximum recursion depth (42) exceeded`)\n\t\t}\n\n\t\t// Process this block\n\t\tconst result = mapKid({ blockID, relID })\n\n\t\t// Process the children\n\t\tconst kidsQuery = query(thread, [\n\t\t\t{ en: '?kidRelID', at: 'relation/childOf', vl: blockID },\n\t\t\t{ en: '?kidRelID', at: 'relation/block', vl: '?kidID' },\n\t\t])\n\t\tconst kidResults = kidsQuery.records.map(function kidsQueryRecordsMapper({ kidID, kidRelID }) {\n\t\t\treturn recurse(kidID as EntityID, kidRelID as EntityID, [...trace, blockID])\n\t\t})\n\n\t\treturn joinResults(result, kidResults)\n\t}\n\treturn recurse(blockID, null, [])\n}\n\n/**\n * Collects all applogs for a note and its entire subtree (descendants).\n *\n * This is a non-reactive utility version for use in non-UI contexts (CLI, scripts, MCP server).\n * It returns a flat array of all applogs found during tree traversal.\n *\n * **Important**: The thread parameter MUST be pre-filtered using `lastWriteWins(withoutDeleted(thread))`\n * to ensure correct tree traversal. Unfiltered threads may:\n * - Include deleted blocks/relations (incorrect tree structure)\n * - Include multiple versions of the same applog (redundant)\n *\n * @param thread - Pre-filtered thread (must be result of `lastWriteWins(withoutDeleted(raw))`)\n * @param blockID - The root block ID to collect from\n * @returns Flat array of all applogs from the block and its descendants\n *\n * @example\n * ```typescript\n * import { collectSubtreeApplogs } from '@note3/utils'\n * import { lastWriteWins, withoutDeleted } from '@wovin/core'\n *\n * const filteredThread = withoutDeleted(lastWriteWins(rawThread))\n * const applogs = collectSubtreeApplogs(filteredThread, blockID)\n * console.log(`Collected ${applogs.length} applogs`)\n * ```\n */\nexport function collectSubtreeApplogs(\n\tthread: ThreadOnlyCurrentNoDeleted,\n\tblockID: EntityID,\n): Applog[] {\n\tconst collectedApplogs: Applog[] = []\n\n\tmapAndRecurseKids(thread, blockID, ({ blockID, relID }) => {\n\t\t// Collect ALL applogs for this block entity\n\t\tconst blockQuery = query(thread, [{ en: blockID }])\n\t\tcollectedApplogs.push(...blockQuery.threadOfAllTrails.applogs)\n\n\t\t// Collect ALL applogs for the relation entity (if present)\n\t\tif (relID) {\n\t\t\tconst relQuery = query(thread, [{ en: relID }])\n\t\t\tcollectedApplogs.push(...relQuery.threadOfAllTrails.applogs)\n\t\t}\n\n\t\treturn undefined\n\t}, (blockResult, kidResults) => {\n\t\treturn undefined\n\t})\n\n\treturn collectedApplogs\n}\n"],"mappings":"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","names":["WARN","LOG","DEBUG","VERBOSE","ERROR","g","queryDivergencesByPrev","computedFnDeepCompare","sourceThread","divergences","observableArrayMap","logsForNode","leafs","log","prevLogs","leafID","thread","ThreadInMemory","createDebugName","autorun","toJS","comparer","QueryNode","logsOfThisNode","variables","prevNode","makeObservable","computed","joinThreads","QueryResult","nodes","untracked","observableArrayMap","thread","node","WARN","LOG","DEBUG","VERBOSE","ERROR","g","globalQueryTimeoutTime","lastWriteWins","computedFnDeepCompare","inverseToOnlyReturnFirstLogs","tolerateAlreadyFiltered","rollingMap","mappedThread","rollingMapper","event","sourceThread","isInitial","isInitEvent","newLogs","toAdd","toRemove","tsCheck","i","log","key","existing","sortApplogsByTs","k","v","autorun","applogThreadComparer","createDebugName","withoutDeleted","deletionLogs","rollingFilter2","obsArrMapName","deleted","observableSetMap","query","threadOrLogs","patternOrPatterns","startVariables","opts","throwOnTimeout","threadFromMaybeArray","patterns","pattersExceptLast","lastPattern","stepResult","queryStep","toJS","queryNodesComparer","pattern","startVars","nodeSet","doQuery","patternWithResolvedVars","variablesToFill","resolveOrRemoveVariables","applogsMatchingStatic","varMapper","createObjMapper","resultNodes","newVarsAndTheirLog","vars","nodeVars","StaticThread","wrapper_default","observableResultNodes","_nodes","queryNot","startNodes","_variablesToFill","newApplogs","filterAndMap","mapper","filtered","name","mapped","mapThreadWith","comparer","queryAndMap","mapDef","debugName","queryResult","mapQueryResultWith","queryEntity","entityID","attributes","prefixAttrs","at","vl","computedStructuralComparer","agentsOfThread","observable","onEvent","action","prev","unsubscribe","onBecomeObserved","entityOverlap","threadA","threadB","entitiesA","entitiesB","en","entityOverlapCount","computedFnDeepCompare","threadA","threadB","computed","entityOverlap","querySingle","threadOrLogs","patternOrPatterns","variables","result","query","ERROR","logsOfThisNode","comparer","thread","pattern","createDebugName","querySingleAndMap","mapDef","resultBox","log","createObjMapper","mapThreadWith","mapQueryResultWith","queryResult","node","applogFieldMap","applog","acc","key","value","prefixAttrs","prefix","attrs","at","prefixAt","attr","threadFromMaybeArray","threadOrLogs","name","ThreadInMemory","throwOnTimeout","globalQueryTimeoutTime","QueryTimeoutError","message","mapAndRecurseKids","thread","blockID","mapKid","joinResults","recurse","relID","trace","result","kidResults","query","kidID","kidRelID","collectSubtreeApplogs","collectedApplogs","blockQuery","relQuery","blockResult"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-KHOUPFOL.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function u(s){if(!s?.length)return[];let o=s.filter(e=>!e.isDeleted).slice();o.sort((e,n)=>e.id<n.id?-1:1);let r=new Set(o.map(e=>e.childOf));if(r.size!==1)throw new Error(`[orderRelations] All relations must have the same parent. Found ${r.size} different parents: ${Array.from(r).join(", ")}`);let t=[],d=new Map,f=new Map;for(let e of o)d.set(e.id,e),f.set(e.block,e);function l(e,n=[]){if(n.includes(e.id)){let i=[...n,e.id].join(" \u2192 ");throw new Error(`[orderRelations] Circular reference detected in relation ordering: ${i}`)}if(n.push(e.id),!e.after)t.unshift(e.id);else{let i=f.get(e.after);if(!i)t.push(e.id);else{t.includes(i.id)||l(i,n);let p=t.indexOf(i.id);p===-1?(console.warn(`[orderRelations] Could not find position after placing relation ${i.id}. Adding relation ${e.id} to end.`),t.push(e.id)):t.splice(p+1,0,e.id)}}let c=o.indexOf(e);c!==-1&&o.splice(c,1)}for(;o.length;){let e=o[0];l(e)}let a=[];for(let e of t){let n=d.get(e);n&&a.push(n)}return a}export{u as a};
|
|
2
|
+
//# sourceMappingURL=chunk-KY36PVHK.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/relation-ordering.ts"],"sourcesContent":["import type { EntityID } from '@wovin/core/applog'\nimport type { RelationInfo } from './types'\n\n/**\n * Orders relations based on their 'after' field (sibling ordering).\n *\n * This is a pure function that takes relations and returns them in the correct order\n * based on their 'after' field, which specifies which sibling block each relation should come after.\n *\n * @param relations - Array of relations to order (all must have same childOf)\n * @returns Ordered array of relations\n * @throws Error if relations have different parents or if circular references are detected\n */\nexport function orderRelations(originalList: readonly RelationInfo[]): RelationInfo[] {\n\tif (!originalList?.length) return []\n\n\t// Filter out deleted relations and create mutable working copy\n\tconst list = originalList.filter(rel => !rel.isDeleted).slice()\n\n\t// Sort by ID to make it deterministic\n\tlist.sort((a, b) => (a.id < b.id) ? -1 : 1)\n\n\t// Validate all relations have the same parent\n\tconst uniqueParents = new Set(list.map(rel => rel.childOf))\n\tif (uniqueParents.size !== 1) {\n\t\tthrow new Error(\n\t\t\t`[orderRelations] All relations must have the same parent. ` +\n\t\t\t`Found ${uniqueParents.size} different parents: ${Array.from(uniqueParents).join(', ')}`\n\t\t)\n\t}\n\n\tconst orderedRelationIDs: EntityID[] = []\n\tconst relIDMap = new Map<EntityID, RelationInfo>()\n\tconst blockToRel = new Map<EntityID, RelationInfo>()\n\n\tfor (const rel of list) {\n\t\trelIDMap.set(rel.id, rel)\n\t\tblockToRel.set(rel.block, rel)\n\t}\n\n\tfunction placeRecursively(rel: RelationInfo, trace: EntityID[] = []) {\n\t\t// Detect circular references\n\t\tif (trace.includes(rel.id)) {\n\t\t\tconst cycle = [...trace, rel.id].join(' → ')\n\t\t\tthrow new Error(\n\t\t\t\t`[orderRelations] Circular reference detected in relation ordering: ${cycle}`\n\t\t\t)\n\t\t}\n\t\ttrace.push(rel.id)\n\n\t\tif (!rel.after) {\n\t\t\t// No 'after' means this goes at the top\n\t\t\torderedRelationIDs.unshift(rel.id)\n\t\t} else {\n\t\t\t// Find the relation we should be after\n\t\t\tconst relWeAreAfter = blockToRel.get(rel.after)\n\t\t\tif (!relWeAreAfter) {\n\t\t\t\t// Referenced block doesn't exist or isn't a child - add to bottom\n\t\t\t\torderedRelationIDs.push(rel.id)\n\t\t\t} else {\n\t\t\t\t// Recursively place the relation we're after (if not already placed)\n\t\t\t\tif (!orderedRelationIDs.includes(relWeAreAfter.id)) {\n\t\t\t\t\tplaceRecursively(relWeAreAfter, trace)\n\t\t\t\t}\n\n\t\t\t\tconst posOfNodeWeAreAfter = orderedRelationIDs.indexOf(relWeAreAfter.id)\n\t\t\t\tif (posOfNodeWeAreAfter === -1) {\n\t\t\t\t\t// This shouldn't happen, but if it does, add to end\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[orderRelations] Could not find position after placing relation ${relWeAreAfter.id}. ` +\n\t\t\t\t\t\t`Adding relation ${rel.id} to end.`\n\t\t\t\t\t)\n\t\t\t\t\torderedRelationIDs.push(rel.id)\n\t\t\t\t} else {\n\t\t\t\t\t// Insert right after the relation we're supposed to be after\n\t\t\t\t\torderedRelationIDs.splice(posOfNodeWeAreAfter + 1, 0, rel.id)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Remove from 'to be placed' list\n\t\tconst index = list.indexOf(rel)\n\t\tif (index !== -1) {\n\t\t\tlist.splice(index, 1)\n\t\t}\n\t}\n\n\t// Place all relations\n\twhile (list.length) {\n\t\tconst toPlace = list[0]\n\t\tplaceRecursively(toPlace)\n\t}\n\n\t// Build final ordered list\n\tconst sortedList: RelationInfo[] = []\n\tfor (const relID of orderedRelationIDs) {\n\t\tconst rel = relIDMap.get(relID)\n\t\tif (rel) {\n\t\t\tsortedList.push(rel)\n\t\t}\n\t}\n\n\treturn sortedList\n}\n"],"mappings":"AAaO,SAASA,EAAeC,EAAuD,CACrF,GAAI,CAACA,GAAc,OAAQ,MAAO,CAAC,EAGnC,IAAMC,EAAOD,EAAa,OAAOE,GAAO,CAACA,EAAI,SAAS,EAAE,MAAM,EAG9DD,EAAK,KAAK,CAACE,EAAGC,IAAOD,EAAE,GAAKC,EAAE,GAAM,GAAK,CAAC,EAG1C,IAAMC,EAAgB,IAAI,IAAIJ,EAAK,IAAIC,GAAOA,EAAI,OAAO,CAAC,EAC1D,GAAIG,EAAc,OAAS,EAC1B,MAAM,IAAI,MACT,mEACSA,EAAc,IAAI,uBAAuB,MAAM,KAAKA,CAAa,EAAE,KAAK,IAAI,CAAC,EACvF,EAGD,IAAMC,EAAiC,CAAC,EAClCC,EAAW,IAAI,IACfC,EAAa,IAAI,IAEvB,QAAWN,KAAOD,EACjBM,EAAS,IAAIL,EAAI,GAAIA,CAAG,EACxBM,EAAW,IAAIN,EAAI,MAAOA,CAAG,EAG9B,SAASO,EAAiBP,EAAmBQ,EAAoB,CAAC,EAAG,CAEpE,GAAIA,EAAM,SAASR,EAAI,EAAE,EAAG,CAC3B,IAAMS,EAAQ,CAAC,GAAGD,EAAOR,EAAI,EAAE,EAAE,KAAK,UAAK,EAC3C,MAAM,IAAI,MACT,sEAAsES,CAAK,EAC5E,CACD,CAGA,GAFAD,EAAM,KAAKR,EAAI,EAAE,EAEb,CAACA,EAAI,MAERI,EAAmB,QAAQJ,EAAI,EAAE,MAC3B,CAEN,IAAMU,EAAgBJ,EAAW,IAAIN,EAAI,KAAK,EAC9C,GAAI,CAACU,EAEJN,EAAmB,KAAKJ,EAAI,EAAE,MACxB,CAEDI,EAAmB,SAASM,EAAc,EAAE,GAChDH,EAAiBG,EAAeF,CAAK,EAGtC,IAAMG,EAAsBP,EAAmB,QAAQM,EAAc,EAAE,EACnEC,IAAwB,IAE3B,QAAQ,KACP,mEAAmED,EAAc,EAAE,qBAChEV,EAAI,EAAE,UAC1B,EACAI,EAAmB,KAAKJ,EAAI,EAAE,GAG9BI,EAAmB,OAAOO,EAAsB,EAAG,EAAGX,EAAI,EAAE,CAE9D,CACD,CAGA,IAAMY,EAAQb,EAAK,QAAQC,CAAG,EAC1BY,IAAU,IACbb,EAAK,OAAOa,EAAO,CAAC,CAEtB,CAGA,KAAOb,EAAK,QAAQ,CACnB,IAAMc,EAAUd,EAAK,CAAC,EACtBQ,EAAiBM,CAAO,CACzB,CAGA,IAAMC,EAA6B,CAAC,EACpC,QAAWC,KAASX,EAAoB,CACvC,IAAMJ,EAAMK,EAAS,IAAIU,CAAK,EAC1Bf,GACHc,EAAW,KAAKd,CAAG,CAErB,CAEA,OAAOc,CACR","names":["orderRelations","originalList","list","rel","a","b","uniqueParents","orderedRelationIDs","relIDMap","blockToRel","placeRecursively","trace","cycle","relWeAreAfter","posOfNodeWeAreAfter","index","toPlace","sortedList","relID"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{l as i,m as p,n as c,o}from"./chunk-POX3PUJK.min.js";function T(t){return{type:"doc",content:[{type:"paragraph",content:t.length?[{type:"text",text:t}]:void 0}]}}function u(t){return t==null?t:t.startsWith("{")?JSON.parse(t):T(t)}function s(t){return t?.content?.map(n=>n?.content).flatMap(n=>n?.map(e=>e?.text)).join("")}function f(t){return r(i,t)}function h(t){return r(p,t)}function C(t){return r(c,t)}function A(t){return r(o,t)}function r(t,n){let e=t.exec(n);return e&&e[2].toLocaleLowerCase()}function E(t,n,e){if(!t.exec(e))return null;let a=n.exec(g(e));return a&&a[2].toLocaleLowerCase()}function _(t,n=o){return n.global||(n=new RegExp(n.source,`${n.flags}g`)),Array.from(t.matchAll(n)).map(e=>e[0])}function g(t){return s(u(t))}export{T as a,u as b,s as c,f as d,h as e,C as f,A as g,r as h,E as i,_ as j,g as k};
|
|
2
|
+
//# sourceMappingURL=chunk-LDNVHZO7.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/note3-utils-nodeps.ts"],"sourcesContent":["import {\n\tRE_ANY_TAG_WITHCONTEXT,\n\tRE_AT_TAG_WITHCONTEXT,\n\tRE_HASH_TAG_WITHCONTEXT,\n\tRE_PLUS_TAG_WITHCONTEXT,\n} from './note3-regex-constants'\n\nexport type TiptapContent = Record<string, any>\n\n// HACK This module exposes utilities without pulling in the entire app\n\nexport function plaintextStringToTiptap(value: string) {\n\treturn {\n\t\ttype: 'doc',\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: 'paragraph',\n\t\t\t\tcontent: !value.length\n\t\t\t\t\t? undefined\n\t\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\ttext: value,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t},\n\t\t],\n\t}\n}\nexport function parseBlockContentValue(value: string) {\n\tif (value === null || value === undefined) {\n\t\treturn value\n\t}\n\tif (!value.startsWith('{')) {\n\t\t// HACK too lazy to do migrations yet\n\t\treturn plaintextStringToTiptap(value)\n\t}\n\treturn JSON.parse(value)\n}\n\nexport function tiptapToPlaintext(tiptap: TiptapContent) {\n\t// HACK: works for now, but...\n\treturn tiptap?.content?.map(c => c?.content).flatMap(c => c?.map(c => c?.text)).join('') as string | null\n}\n\nexport function plainContentMatchHashTag(content: string) {\n\treturn plainContentMatchTagGeneric(RE_HASH_TAG_WITHCONTEXT, content)\n}\nexport function plainContentMatchPlusTag(content: string) {\n\treturn plainContentMatchTagGeneric(RE_PLUS_TAG_WITHCONTEXT, content)\n}\nexport function plainContentMatchAtTag(content: string) {\n\treturn plainContentMatchTagGeneric(RE_AT_TAG_WITHCONTEXT, content)\n}\nexport function plainContentMatchAnyTag(content: string) {\n\treturn plainContentMatchTagGeneric(RE_ANY_TAG_WITHCONTEXT, content)\n}\nexport function plainContentMatchTagGeneric(regex: RegExp, content: string) {\n\tconst match = regex.exec(content)\n\treturn match && match[2].toLocaleLowerCase()\n}\nexport function rawContentMatchTag(regexCheap: RegExp, regex: RegExp, vl) {\n\tconst cheapMatch = regexCheap.exec(vl) // (i) cheap match before parsing tiptap content\n\tif (!cheapMatch) return null\n\tconst match = regex.exec(contentVlToPlaintext(vl)) // HACK: use materialized view\n\treturn match && match[2].toLocaleLowerCase()\n}\n\nexport function getAllTagsInText(text: string, regex = RE_ANY_TAG_WITHCONTEXT) {\n\tif (!regex.global) regex = new RegExp(regex.source, `${regex.flags}g`)\n\treturn Array.from(text.matchAll(regex)).map(match => match[0])\n}\nexport function contentVlToPlaintext(content: string) {\n\treturn tiptapToPlaintext(parseBlockContentValue(content))\n}\n"],"mappings":"4DAWO,SAASA,EAAwBC,EAAe,CACtD,MAAO,CACN,KAAM,MACN,QAAS,CACR,CACC,KAAM,YACN,QAAUA,EAAM,OAEb,CACD,CACC,KAAM,OACN,KAAMA,CACP,CACD,EANE,MAOJ,CACD,CACD,CACD,CACO,SAASC,EAAuBD,EAAe,CACrD,OAAIA,GAAU,KACNA,EAEHA,EAAM,WAAW,GAAG,EAIlB,KAAK,MAAMA,CAAK,EAFfD,EAAwBC,CAAK,CAGtC,CAEO,SAASE,EAAkBC,EAAuB,CAExD,OAAOA,GAAQ,SAAS,IAAIC,GAAKA,GAAG,OAAO,EAAE,QAAQA,GAAKA,GAAG,IAAIA,GAAKA,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,CACxF,CAEO,SAASC,EAAyBC,EAAiB,CACzD,OAAOC,EAA4BC,EAAyBF,CAAO,CACpE,CACO,SAASG,EAAyBH,EAAiB,CACzD,OAAOC,EAA4BG,EAAyBJ,CAAO,CACpE,CACO,SAASK,EAAuBL,EAAiB,CACvD,OAAOC,EAA4BK,EAAuBN,CAAO,CAClE,CACO,SAASO,EAAwBP,EAAiB,CACxD,OAAOC,EAA4BO,EAAwBR,CAAO,CACnE,CACO,SAASC,EAA4BQ,EAAeT,EAAiB,CAC3E,IAAMU,EAAQD,EAAM,KAAKT,CAAO,EAChC,OAAOU,GAASA,EAAM,CAAC,EAAE,kBAAkB,CAC5C,CACO,SAASC,EAAmBC,EAAoBH,EAAeI,EAAI,CAEzE,GAAI,CADeD,EAAW,KAAKC,CAAE,EACpB,OAAO,KACxB,IAAMH,EAAQD,EAAM,KAAKK,EAAqBD,CAAE,CAAC,EACjD,OAAOH,GAASA,EAAM,CAAC,EAAE,kBAAkB,CAC5C,CAEO,SAASK,EAAiBC,EAAcP,EAAQD,EAAwB,CAC9E,OAAKC,EAAM,SAAQA,EAAQ,IAAI,OAAOA,EAAM,OAAQ,GAAGA,EAAM,KAAK,GAAG,GAC9D,MAAM,KAAKO,EAAK,SAASP,CAAK,CAAC,EAAE,IAAIC,GAASA,EAAM,CAAC,CAAC,CAC9D,CACO,SAASI,EAAqBd,EAAiB,CACrD,OAAOJ,EAAkBD,EAAuBK,CAAO,CAAC,CACzD","names":["plaintextStringToTiptap","value","parseBlockContentValue","tiptapToPlaintext","tiptap","c","plainContentMatchHashTag","content","plainContentMatchTagGeneric","RE_HASH_TAG_WITHCONTEXT","plainContentMatchPlusTag","RE_PLUS_TAG_WITHCONTEXT","plainContentMatchAtTag","RE_AT_TAG_WITHCONTEXT","plainContentMatchAnyTag","RE_ANY_TAG_WITHCONTEXT","regex","match","rawContentMatchTag","regexCheap","vl","contentVlToPlaintext","getAllTagsInText","text"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var g=Object.create;var f=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var m=(b,a)=>()=>(a||b((a={exports:{}}).exports,a),a.exports);var l=(b,a,c,e)=>{if(a&&typeof a=="object"||typeof a=="function")for(let d of i(a))!k.call(b,d)&&d!==c&&f(b,d,{get:()=>a[d],enumerable:!(e=h(a,d))||e.enumerable});return b};var n=(b,a,c)=>(c=b!=null?g(j(b)):{},l(a||!b||!b.__esModule?f(c,"default",{value:b,enumerable:!0}):c,b));export{m as a,n as b};
|
|
2
|
+
//# sourceMappingURL=chunk-MXMMU6NF.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as i}from"./chunk-5TTMWYXD.min.js";var{WARN:R,LOG:d,DEBUG:p,VERBOSE:m,ERROR:l}=i.setup(i.DEBUG);function y(t){let e;return()=>e||(e=t())}async function P(t){let e=t.filter(r=>!!r).map(r=>typeof r=="function"?r():r);if(!e.length)throw l("[racePromises] no promise passed",t);return new Promise(async(r,o)=>{let s=!1,n=await Promise.allSettled(e.map(async a=>{let c=await a;s=!0,r(c)}));s||o(new AggregateError(n.map(a=>a.reason)))})}async function w(t){let e=[];for await(let r of t)e.push(r);return e}async function*h(t){let e=t.stream().getReader();try{for(;;){let{done:r,value:o}=await e.read();if(r)break;yield o}}finally{e.releaseLock()}}function u(t,e,r,o=[]){let s=e(t);if(!s)return t;let n=r(s);if(o.includes(n))throw l("[recurseWithLoopProtection] loop detected",{current:t,next:s,trace:o});return u(s,e,r,[...o,n])}export{y as a,P as b,w as c,h as d,u as e};
|
|
2
|
+
//# sourceMappingURL=chunk-O72M27NE.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers.ts"],"sourcesContent":["import { Logger } from 'besonders-logger'\n\nconst { WARN, LOG, DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.DEBUG) // eslint-disable-line unused-imports/no-unused-vars\n\nexport function lazyVal<R>(func: () => R): () => R {\n\tlet val: R\n\treturn () => {\n\t\tif (val) return val\n\t\treturn val = func()\n\t}\n}\n\n/** Promise.any but also allows to pass functions to call, or falsy values to skip */\nexport async function racePromises<R>(promises: Array<Promise<R> | (() => Promise<R>) | null | undefined | false>): Promise<R> {\n\tconst filtered = promises\n\t\t.filter(f => !!f)\n\t\t.map(maybeFunc => typeof maybeFunc === 'function' ? maybeFunc() : maybeFunc) as Array<Promise<R>>\n\tif (!filtered.length) throw ERROR(`[racePromises] no promise passed`, promises)\n\n\t// return await Promise.any(filtered) - swallows error messages\n\treturn new Promise(async (resolve, reject) => {\n\t\tlet resolved = false\n\t\tconst results = await Promise.allSettled(filtered.map(async (promise) => {\n\t\t\tconst result = await promise\n\t\t\t// if (predicate(result)) return result\n\t\t\tresolved = true\n\t\t\tresolve(result)\n\t\t}))\n\n\t\tif (!resolved) {\n\t\t\treject(\n\t\t\t\tnew AggregateError(\n\t\t\t\t\tresults.map(r => (r as PromiseRejectedResult).reason /* anyways all are rejected */),\n\t\t\t\t\t// `[racePromises] all errored:`,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t})\n}\n\nexport async function asyncIterableToArray<R>(iterable: AsyncIterable<R>): Promise<R[]> {\n\tconst result: R[] = []\n\tfor await (const i of iterable) result.push(i)\n\treturn result\n}\nexport async function* blobToAsyncIterable(blob: Blob) {\n\tconst reader = blob.stream().getReader()\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read()\n\t\t\tif (done) break\n\t\t\tyield value\n\t\t}\n\t} finally {\n\t\treader.releaseLock()\n\t}\n}\nexport function recurseWithLoopProtection<T, ID>(\n\tcurrent: T,\n\tgetNext: (c: T) => T,\n\tgetID: (c: T) => ID,\n\ttrace: ID[] = [],\n) {\n\tconst next = getNext(current)\n\tif (!next) return current\n\tconst id = getID(next)\n\tif (trace.includes(id)) {\n\t\tthrow ERROR('[recurseWithLoopProtection] loop detected', { current, next, trace })\n\t}\n\treturn recurseWithLoopProtection(next, getNext, getID, [...trace, id])\n}\n"],"mappings":"4CAEA,GAAM,CAAE,KAAAA,EAAM,IAAAC,EAAK,MAAAC,EAAO,QAAAC,EAAS,MAAAC,CAAM,EAAIC,EAAO,MAAMA,EAAO,KAAK,EAE/D,SAASC,EAAWC,EAAwB,CAClD,IAAIC,EACJ,MAAO,IACFA,IACGA,EAAMD,EAAK,EAEpB,CAGA,eAAsBE,EAAgBC,EAAyF,CAC9H,IAAMC,EAAWD,EACf,OAAOE,GAAK,CAAC,CAACA,CAAC,EACf,IAAIC,GAAa,OAAOA,GAAc,WAAaA,EAAU,EAAIA,CAAS,EAC5E,GAAI,CAACF,EAAS,OAAQ,MAAMP,EAAM,mCAAoCM,CAAQ,EAG9E,OAAO,IAAI,QAAQ,MAAOI,EAASC,IAAW,CAC7C,IAAIC,EAAW,GACTC,EAAU,MAAM,QAAQ,WAAWN,EAAS,IAAI,MAAOO,GAAY,CACxE,IAAMC,EAAS,MAAMD,EAErBF,EAAW,GACXF,EAAQK,CAAM,CACf,CAAC,CAAC,EAEGH,GACJD,EACC,IAAI,eACHE,EAAQ,IAAIG,GAAMA,EAA4B,MAAqC,CAEpF,CACD,CAEF,CAAC,CACF,CAEA,eAAsBC,EAAwBC,EAA0C,CACvF,IAAMH,EAAc,CAAC,EACrB,cAAiBI,KAAKD,EAAUH,EAAO,KAAKI,CAAC,EAC7C,OAAOJ,CACR,CACA,eAAuBK,EAAoBC,EAAY,CACtD,IAAMC,EAASD,EAAK,OAAO,EAAE,UAAU,EACvC,GAAI,CACH,OAAa,CACZ,GAAM,CAAE,KAAAE,EAAM,MAAAC,CAAM,EAAI,MAAMF,EAAO,KAAK,EAC1C,GAAIC,EAAM,MACV,MAAMC,CACP,CACD,QAAE,CACDF,EAAO,YAAY,CACpB,CACD,CACO,SAASG,EACfC,EACAC,EACAC,EACAC,EAAc,CAAC,EACd,CACD,IAAMC,EAAOH,EAAQD,CAAO,EAC5B,GAAI,CAACI,EAAM,OAAOJ,EAClB,IAAMK,EAAKH,EAAME,CAAI,EACrB,GAAID,EAAM,SAASE,CAAE,EACpB,MAAM/B,EAAM,4CAA6C,CAAE,QAAA0B,EAAS,KAAAI,EAAM,MAAAD,CAAM,CAAC,EAElF,OAAOJ,EAA0BK,EAAMH,EAASC,EAAO,CAAC,GAAGC,EAAOE,CAAE,CAAC,CACtE","names":["WARN","LOG","DEBUG","VERBOSE","ERROR","g","lazyVal","func","val","racePromises","promises","filtered","f","maybeFunc","resolve","reject","resolved","results","promise","result","r","asyncIterableToArray","iterable","i","blobToAsyncIterable","blob","reader","done","value","recurseWithLoopProtection","current","getNext","getID","trace","next","id"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var s={content:[{type:"paragraph"}],type:"doc"},c=2,T=new RegExp("[a-zA-Z0-9_:+/-]"),r=new RegExp("[a-zA-Z]"),e=new RegExp(`(?=${T.source}*${r.source})${T.source}{${c},}`),E=new RegExp(`#(${e.source})`),t=new RegExp(`\\+(${e.source})`),p=new RegExp(`@(${e.source})`),R=new RegExp(`([#+@])(${e.source})`),o=/(^|\s|\()/,_=/(\b|$)/,n=new RegExp(`${o.source}#(${e.source})${_.source}`),x=new RegExp(`${o.source}\\+(${e.source})${_.source}`),A=new RegExp(`${o.source}@(${e.source})${_.source}`),$=new RegExp(`${o.source}([#+@])(${e.source})${_.source}`);export{s as a,c as b,T as c,r as d,e,E as f,t as g,p as h,R as i,o as j,_ as k,n as l,x as m,A as n,$ as o};
|
|
2
|
+
//# sourceMappingURL=chunk-POX3PUJK.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/note3-regex-constants.ts"],"sourcesContent":["// Regex constants for tag matching in note3\n// Extracted to separate file to avoid heavy dependencies\n\n// HACK regexp lints are too complex for 10pm\n/* eslint-disable regexp/no-empty-capturing-group */\n/* eslint-disable regexp/prefer-w */\n/* eslint-disable regexp/use-ignore-case */\nexport const TIPTAP_EMPTY = { content: [{ type: 'paragraph' }], type: 'doc' }\nexport const TAG_MIN_LENGTH = 2 // HACK: for sanity of query performance // ? but are short queries really not needed?\nexport const RE_TAG_BODY_CHAR = new RegExp(`[a-zA-Z0-9_:+/-]`)\nexport const RE_TAG_BODY_REQUIRED_CHAR = new RegExp(`[a-zA-Z]`)\nexport const RE_TAG_BODY = new RegExp(\n\t`(?=${RE_TAG_BODY_CHAR.source}*${RE_TAG_BODY_REQUIRED_CHAR.source})` // Lookahead to ensure at least one letter char in the tag name\n\t\t+ `${RE_TAG_BODY_CHAR.source}{${TAG_MIN_LENGTH},}`,\n)\nexport const RE_HASH_TAG_ONLY = new RegExp(`#(${RE_TAG_BODY.source})`)\nexport const RE_PLUS_TAG_ONLY = new RegExp(`\\\\+(${RE_TAG_BODY.source})`)\nexport const RE_AT_TAG_ONLY = new RegExp(`@(${RE_TAG_BODY.source})`)\nexport const RE_ANY_TAG_ONLY = new RegExp(`([#+@])(${RE_TAG_BODY.source})`)\n// context-aware matching\n\nexport const RE_TAG_CONTEXT_PRE = /(^|\\s|\\()/\nexport const RE_TAG_CONTEXT_POST = /(\\b|$)/ // (i) \\b also matches if the tag continues with e.g. /\nexport const RE_HASH_TAG_WITHCONTEXT = new RegExp(`${RE_TAG_CONTEXT_PRE.source}#(${RE_TAG_BODY.source})${RE_TAG_CONTEXT_POST.source}`)\nexport const RE_PLUS_TAG_WITHCONTEXT = new RegExp(`${RE_TAG_CONTEXT_PRE.source}\\\\+(${RE_TAG_BODY.source})${RE_TAG_CONTEXT_POST.source}`)\nexport const RE_AT_TAG_WITHCONTEXT = new RegExp(`${RE_TAG_CONTEXT_PRE.source}@(${RE_TAG_BODY.source})${RE_TAG_CONTEXT_POST.source}`)\nexport const RE_ANY_TAG_WITHCONTEXT = new RegExp(`${RE_TAG_CONTEXT_PRE.source}([#+@])(${RE_TAG_BODY.source})${RE_TAG_CONTEXT_POST.source}`)\n"],"mappings":"AAOO,IAAMA,EAAe,CAAE,QAAS,CAAC,CAAE,KAAM,WAAY,CAAC,EAAG,KAAM,KAAM,EAC/DC,EAAiB,EACjBC,EAAmB,IAAI,OAAO,kBAAkB,EAChDC,EAA4B,IAAI,OAAO,UAAU,EACjDC,EAAc,IAAI,OAC9B,MAAMF,EAAiB,MAAM,IAAIC,EAA0B,MAAM,IAC3DD,EAAiB,MAAM,IAAID,CAAc,IAChD,EACaI,EAAmB,IAAI,OAAO,KAAKD,EAAY,MAAM,GAAG,EACxDE,EAAmB,IAAI,OAAO,OAAOF,EAAY,MAAM,GAAG,EAC1DG,EAAiB,IAAI,OAAO,KAAKH,EAAY,MAAM,GAAG,EACtDI,EAAkB,IAAI,OAAO,WAAWJ,EAAY,MAAM,GAAG,EAG7DK,EAAqB,YACrBC,EAAsB,SACtBC,EAA0B,IAAI,OAAO,GAAGF,EAAmB,MAAM,KAAKL,EAAY,MAAM,IAAIM,EAAoB,MAAM,EAAE,EACxHE,EAA0B,IAAI,OAAO,GAAGH,EAAmB,MAAM,OAAOL,EAAY,MAAM,IAAIM,EAAoB,MAAM,EAAE,EAC1HG,EAAwB,IAAI,OAAO,GAAGJ,EAAmB,MAAM,KAAKL,EAAY,MAAM,IAAIM,EAAoB,MAAM,EAAE,EACtHI,EAAyB,IAAI,OAAO,GAAGL,EAAmB,MAAM,WAAWL,EAAY,MAAM,IAAIM,EAAoB,MAAM,EAAE","names":["TIPTAP_EMPTY","TAG_MIN_LENGTH","RE_TAG_BODY_CHAR","RE_TAG_BODY_REQUIRED_CHAR","RE_TAG_BODY","RE_HASH_TAG_ONLY","RE_PLUS_TAG_ONLY","RE_AT_TAG_ONLY","RE_ANY_TAG_ONLY","RE_TAG_CONTEXT_PRE","RE_TAG_CONTEXT_POST","RE_HASH_TAG_WITHCONTEXT","RE_PLUS_TAG_WITHCONTEXT","RE_AT_TAG_WITHCONTEXT","RE_ANY_TAG_WITHCONTEXT"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as f}from"./chunk-KY36PVHK.min.js";import{b as r,c as s}from"./chunk-LDNVHZO7.min.js";function I(o,e){return!(e.en&&o.en!==e.en||e.at&&o.at!==e.at||e.vl!==void 0&&o.vl!==e.vl)}function y(o,e){return o.applogs.filter(t=>I(t,{at:"relation/childOf",vl:e})).map(t=>t.en)}function g(o,e){let n=new Set,t=new Set;for(let l of o.applogs)l.at==="relation/block"&&l.vl===e&&n.add(l.en);for(let l of n)for(let i of o.applogs)i.en===l&&i.at==="relation/childOf"&&i.vl!==null&&t.add(i.vl);return Array.from(t)}function c(o,e){let n={id:e};for(let t of o.applogs)if(t.en===e)switch(t.at){case"relation/block":n.block=t.vl;break;case"relation/childOf":n.childOf=t.vl;break;case"relation/after":n.after=t.vl;break;case"relation/isExpanded":n.isExpanded=t.vl;break;case"relation/isMirror":n.isMirror=t.vl;break;case"relation/isReply":n.isReply=t.vl;break;case"isDeleted":n.isDeleted=t.vl;break}return!n.block||n.childOf===void 0?null:n}function E(o,e){let t=o.applogs.filter(l=>l.at==="relation/childOf"&&l.vl===e).map(l=>l.en).map(l=>c(o,l)).filter(l=>l!==null);return f(t)}function b(o,e){return o.applogs.filter(t=>t.at==="relation/block"&&t.vl===e).map(t=>t.en).map(t=>c(o,t)).filter(t=>t!==null)}function u(o,e){let n=o.applogs.find(t=>t.en===e&&t.at==="block/content");return n?r(n.vl):null}function k(o,e){let n=u(o,e);return n?s(n):null}function v(o){let e=new Set;for(let i of o.applogs)i.at==="block/content"&&e.add(i.en);let n=new Set,t=new Map;for(let i of o.applogs)i.at==="relation/block"&&t.set(i.vl,i.en);for(let[i,p]of t)for(let a of o.applogs)if(a.en===p&&a.at==="relation/childOf"){a.vl!==null&&n.add(i);break}return Array.from(e).filter(i=>!n.has(i)).sort()}export{y as a,g as b,E as c,b as d,u as e,k as f,v as g};
|
|
2
|
+
//# sourceMappingURL=chunk-XL6QVLYO.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/queries.ts"],"sourcesContent":["import type { Applog, EntityID } from '@wovin/core/applog'\nimport type { Thread } from '@wovin/core/thread'\nimport type { RelationInfo } from './types'\nimport { parseBlockContentValue, tiptapToPlaintext, type TiptapContent } from './note3-utils-nodeps'\nimport { orderRelations } from './relation-ordering'\n\n/**\n * Helper to match applog against a pattern\n */\nfunction matchesPattern(applog: Applog, pattern: { en?: EntityID; at?: string; vl?: any }): boolean {\n\tif (pattern.en && applog.en !== pattern.en) return false\n\tif (pattern.at && applog.at !== pattern.at) return false\n\tif (pattern.vl !== undefined && applog.vl !== pattern.vl) return false\n\treturn true\n}\n\n/**\n * Get all child block IDs for a given parent block\n * @param thread - The thread to query\n * @param parentId - The parent block's entity ID\n * @returns Array of child block IDs (unordered - use getChildRelations for ordered)\n */\nexport function getChildIDs(thread: Thread, parentId: EntityID): EntityID[] {\n\tconst applogs = thread.applogs.filter(log =>\n\t\tmatchesPattern(log, { at: 'relation/childOf', vl: parentId })\n\t)\n\treturn applogs.map(log => log.en)\n}\n\n/**\n * Get all parent block IDs for a given block\n * @param thread - The thread to query\n * @param blockId - The block's entity ID\n * @returns Array of parent block IDs (usually just one, but can be multiple)\n */\nexport function getParentIDs(thread: Thread, blockId: EntityID): EntityID[] {\n\t// Find all relations where this block is the child\n\tconst relationIDs = new Set<EntityID>()\n\tconst parentIDs = new Set<EntityID>()\n\n\tfor (const log of thread.applogs) {\n\t\t// Find relations that reference this block\n\t\tif (log.at === 'relation/block' && log.vl === blockId) {\n\t\t\trelationIDs.add(log.en)\n\t\t}\n\t}\n\n\t// For each relation, find its parent\n\tfor (const relID of relationIDs) {\n\t\tfor (const log of thread.applogs) {\n\t\t\tif (log.en === relID && log.at === 'relation/childOf' && log.vl !== null) {\n\t\t\t\tparentIDs.add(log.vl as EntityID)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Array.from(parentIDs)\n}\n\n/**\n * Build RelationInfo object from applogs for a specific relation entity\n */\nfunction buildRelationInfo(thread: Thread, relationID: EntityID): RelationInfo | null {\n\tconst attrs: Partial<RelationInfo> = { id: relationID }\n\n\tfor (const log of thread.applogs) {\n\t\tif (log.en !== relationID) continue\n\n\t\tswitch (log.at) {\n\t\t\tcase 'relation/block':\n\t\t\t\tattrs.block = log.vl as EntityID\n\t\t\t\tbreak\n\t\t\tcase 'relation/childOf':\n\t\t\t\tattrs.childOf = log.vl as EntityID\n\t\t\t\tbreak\n\t\t\tcase 'relation/after':\n\t\t\t\tattrs.after = log.vl as EntityID | null\n\t\t\t\tbreak\n\t\t\tcase 'relation/isExpanded':\n\t\t\t\tattrs.isExpanded = log.vl as boolean\n\t\t\t\tbreak\n\t\t\tcase 'relation/isMirror':\n\t\t\t\tattrs.isMirror = log.vl as boolean\n\t\t\t\tbreak\n\t\t\tcase 'relation/isReply':\n\t\t\t\tattrs.isReply = log.vl as boolean\n\t\t\t\tbreak\n\t\t\tcase 'isDeleted':\n\t\t\t\tattrs.isDeleted = log.vl as boolean\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\t// Validate required fields\n\tif (!attrs.block || attrs.childOf === undefined) {\n\t\treturn null\n\t}\n\n\treturn attrs as RelationInfo\n}\n\n/**\n * Get ordered child relations for a given parent block\n * @param thread - The thread to query\n * @param parentId - The parent block's entity ID\n * @returns Ordered array of RelationInfo objects\n */\nexport function getChildRelations(thread: Thread, parentId: EntityID): RelationInfo[] {\n\t// Find all relation IDs for this parent\n\tconst relationIDs = thread.applogs\n\t\t.filter(log => log.at === 'relation/childOf' && log.vl === parentId)\n\t\t.map(log => log.en)\n\n\t// Build RelationInfo objects\n\tconst relations = relationIDs\n\t\t.map(relID => buildRelationInfo(thread, relID))\n\t\t.filter((rel): rel is RelationInfo => rel !== null)\n\n\t// Order them\n\treturn orderRelations(relations)\n}\n\n/**\n * Get parent relations (placements) for a given block\n * @param thread - The thread to query\n * @param blockId - The block's entity ID\n * @returns Array of RelationInfo objects (unordered)\n */\nexport function getParentRelations(thread: Thread, blockId: EntityID): RelationInfo[] {\n\t// Find all relation IDs where this block is referenced\n\tconst relationIDs = thread.applogs\n\t\t.filter(log => log.at === 'relation/block' && log.vl === blockId)\n\t\t.map(log => log.en)\n\n\t// Build RelationInfo objects\n\treturn relationIDs\n\t\t.map(relID => buildRelationInfo(thread, relID))\n\t\t.filter((rel): rel is RelationInfo => rel !== null)\n}\n\n/**\n * Get the content of a block as TiptapContent\n * @param thread - The thread to query\n * @param blockId - The block's entity ID\n * @returns TiptapContent object or null if not found\n */\nexport function getContent(thread: Thread, blockId: EntityID): TiptapContent | null {\n\tconst contentLog = thread.applogs.find(log =>\n\t\tlog.en === blockId && log.at === 'block/content'\n\t)\n\n\tif (!contentLog) return null\n\n\treturn parseBlockContentValue(contentLog.vl as string)\n}\n\n/**\n * Get the plain text content of a block\n * @param thread - The thread to query\n * @param blockId - The block's entity ID\n * @returns Plain text string or null if not found\n */\nexport function getContentText(thread: Thread, blockId: EntityID): string | null {\n\tconst content = getContent(thread, blockId)\n\tif (!content) return null\n\treturn tiptapToPlaintext(content)\n}\n\n/**\n * Get all root block IDs (blocks without parents)\n * @param thread - The thread to query\n * @returns Array of root block IDs, sorted by entity ID\n */\nexport function getRootIDs(thread: Thread): EntityID[] {\n\t// Find all blocks (entities with block/content attribute)\n\tconst allBlockIDs = new Set<EntityID>()\n\tfor (const log of thread.applogs) {\n\t\tif (log.at === 'block/content') {\n\t\t\tallBlockIDs.add(log.en)\n\t\t}\n\t}\n\n\t// Find all blocks that have parent relations\n\tconst blocksWithParents = new Set<EntityID>()\n\tconst relationsByBlock = new Map<EntityID, EntityID>() // block -> relation\n\n\tfor (const log of thread.applogs) {\n\t\tif (log.at === 'relation/block') {\n\t\t\trelationsByBlock.set(log.vl as EntityID, log.en)\n\t\t}\n\t}\n\n\t// Check which relations have non-null parents\n\tfor (const [blockID, relationID] of relationsByBlock) {\n\t\tfor (const log of thread.applogs) {\n\t\t\tif (log.en === relationID && log.at === 'relation/childOf') {\n\t\t\t\tif (log.vl !== null) {\n\t\t\t\t\tblocksWithParents.add(blockID)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Root blocks = all blocks - blocks with parents\n\tconst rootBlocks = Array.from(allBlockIDs).filter(id => !blocksWithParents.has(id))\n\n\t// Sort by entity ID for determinism\n\treturn rootBlocks.sort()\n}\n"],"mappings":"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","names":["matchesPattern","applog","pattern","getChildIDs","thread","parentId","log","getParentIDs","blockId","relationIDs","parentIDs","relID","buildRelationInfo","relationID","attrs","getChildRelations","relations","rel","orderRelations","getParentRelations","getContent","contentLog","parseBlockContentValue","getContentText","content","tiptapToPlaintext","getRootIDs","allBlockIDs","blocksWithParents","relationsByBlock","blockID","id"]}
|