@mulmoclaude/core 3.7.0 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/collection/core/itemId.d.ts +28 -0
- package/dist/collection/firestore.cjs +9 -1
- package/dist/collection/firestore.cjs.map +1 -1
- package/dist/collection/firestore.js +10 -2
- package/dist/collection/firestore.js.map +1 -1
- package/dist/collection/index.cjs +55 -66
- package/dist/collection/index.cjs.map +1 -1
- package/dist/collection/index.d.ts +1 -1
- package/dist/collection/index.js +3 -15
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/registry/server/index.cjs +19 -19
- package/dist/collection/registry/server/index.cjs.map +1 -1
- package/dist/collection/registry/server/index.js +2 -2
- package/dist/collection/server/firestoreDocs.d.ts +18 -0
- package/dist/collection/server/host.d.ts +29 -0
- package/dist/collection/server/index.cjs +70 -62
- package/dist/collection/server/index.d.ts +2 -3
- package/dist/collection/server/index.js +4 -4
- package/dist/collection/server/io.d.ts +5 -3
- package/dist/collection/server/manageTool.d.ts +0 -4
- package/dist/collection/server/publishManifest.d.ts +1 -0
- package/dist/collection/server/publishProject.d.ts +171 -2
- package/dist/collection-watchers/index.cjs +82 -38
- package/dist/collection-watchers/index.cjs.map +1 -1
- package/dist/collection-watchers/index.js +67 -23
- package/dist/collection-watchers/index.js.map +1 -1
- package/dist/{store-_61sO8K8.js → discovery-B9zdNkgW.js} +2525 -2354
- package/dist/discovery-B9zdNkgW.js.map +1 -0
- package/dist/{store-5_P_NsGa.cjs → discovery-BsXiDZBR.cjs} +2545 -2362
- package/dist/discovery-BsXiDZBR.cjs.map +1 -0
- package/dist/feeds/index.cjs +4 -4
- package/dist/feeds/index.js +2 -2
- package/dist/feeds/server/index.cjs +14 -14
- package/dist/feeds/server/index.cjs.map +1 -1
- package/dist/feeds/server/index.js +4 -4
- package/dist/firestore/listen.d.ts +4 -0
- package/dist/google/index.cjs +16 -16
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.js +2 -2
- package/dist/{ingestTypes-CEi-Ot7F.js → ingestTypes-B312BwXg.js} +2 -2
- package/dist/{ingestTypes-CEi-Ot7F.js.map → ingestTypes-B312BwXg.js.map} +1 -1
- package/dist/{ingestTypes-iaiq33Ph.cjs → ingestTypes-B4XfrUoq.cjs} +3 -3
- package/dist/{ingestTypes-iaiq33Ph.cjs.map → ingestTypes-B4XfrUoq.cjs.map} +1 -1
- package/dist/{calendarGrid-CQ8MVSRb.js → itemId-DfTm08jm.js} +34 -2
- package/dist/itemId-DfTm08jm.js.map +1 -0
- package/dist/{calendarGrid-DGILaVxI.cjs → itemId-Dzrr3vs5.cjs} +45 -1
- package/dist/itemId-Dzrr3vs5.cjs.map +1 -0
- package/dist/listen-D5av7GzB.js +22 -0
- package/dist/listen-D5av7GzB.js.map +1 -0
- package/dist/listen-UZA68Upt.cjs +45 -0
- package/dist/listen-UZA68Upt.cjs.map +1 -0
- package/dist/{promptSafety-CpiME8pj.js → promptSafety-CSdyp7RF.js} +2 -2
- package/dist/{promptSafety-CpiME8pj.js.map → promptSafety-CSdyp7RF.js.map} +1 -1
- package/dist/{promptSafety-NNGViiCr.cjs → promptSafety-CWqYq-NS.cjs} +8 -8
- package/dist/{promptSafety-NNGViiCr.cjs.map → promptSafety-CWqYq-NS.cjs.map} +1 -1
- package/dist/remote-host/server/hostRunner.d.ts +2 -4
- package/dist/remote-host/server/index.cjs +4 -19
- package/dist/remote-host/server/index.cjs.map +1 -1
- package/dist/remote-host/server/index.js +1 -16
- package/dist/remote-host/server/index.js.map +1 -1
- package/dist/{server-CWZyg8fn.cjs → server-X_magqUa.cjs} +620 -734
- package/dist/server-X_magqUa.cjs.map +1 -0
- package/dist/{server-B48Jyxcj.js → server-zcM1ViCE.js} +418 -568
- package/dist/server-zcM1ViCE.js.map +1 -0
- package/dist/whisper/index.cjs +1 -1
- package/dist/whisper/index.js +1 -1
- package/package.json +1 -1
- package/dist/calendarGrid-CQ8MVSRb.js.map +0 -1
- package/dist/calendarGrid-DGILaVxI.cjs.map +0 -1
- package/dist/collection/core/shortHexId.d.ts +0 -8
- package/dist/collection/server/publish.d.ts +0 -56
- package/dist/server-B48Jyxcj.js.map +0 -1
- package/dist/server-CWZyg8fn.cjs.map +0 -1
- package/dist/store-5_P_NsGa.cjs.map +0 -1
- package/dist/store-_61sO8K8.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generated record id: a v4 UUID with its hyphens stripped — 32 lowercase hex
|
|
3
|
+
* characters, 122 bits.
|
|
4
|
+
*
|
|
5
|
+
* The ONE generator behind both blank-id create paths — the server's
|
|
6
|
+
* `generateItemId()` (../server/io) delegates here, so the UI's pre-filled id
|
|
7
|
+
* and the id a blank-id POST mints are the same thing rather than two
|
|
8
|
+
* implementations that have to agree.
|
|
9
|
+
*
|
|
10
|
+
* It replaced an 8-hex-char id, whose 32 bits collided at a 1.2% rate across
|
|
11
|
+
* 10k records — and a collision surfaced as `item '<id>' already exists`, which
|
|
12
|
+
* named a duplicate that did not exist (#2851).
|
|
13
|
+
*
|
|
14
|
+
* **The hyphens have to go.** A record id in a `googleCalendar` collection is
|
|
15
|
+
* sent to Google as the caller-chosen event id, and Google takes base32hex only
|
|
16
|
+
* (`isClientSettableEventId`, ../../google/pushPlan) — a hyphenated UUID is
|
|
17
|
+
* refused, so every UI-created record would push as "the record id cannot be
|
|
18
|
+
* used as a Google event id". Hex is a subset of base32hex, so the stripped
|
|
19
|
+
* form satisfies both that and `SAFE_RECORD_ID_PATTERN` (the id is also the
|
|
20
|
+
* `<id>.json` filename stem).
|
|
21
|
+
*/
|
|
22
|
+
export declare function newItemId(): string;
|
|
23
|
+
/** @deprecated Use {@link newItemId}. Kept as a compatibility export because
|
|
24
|
+
* `@mulmoclaude/core/collection` is public API (same reason as
|
|
25
|
+
* `CollectionActionWhen` in ./schema). It is the NEW generator, not the old
|
|
26
|
+
* 8-hex one: that width is the bug #2851 reported, and leaving a copy of it
|
|
27
|
+
* reachable under an old name would keep shipping it. */
|
|
28
|
+
export declare const shortHexId: typeof newItemId;
|
|
@@ -42,7 +42,15 @@ function createFirestoreDocs(database) {
|
|
|
42
42
|
if (!(await transaction.get(ref)).exists()) return false;
|
|
43
43
|
transaction.delete(ref);
|
|
44
44
|
return true;
|
|
45
|
-
})
|
|
45
|
+
}),
|
|
46
|
+
watch: (collectionPath, onChanged, onError) => {
|
|
47
|
+
let seen = false;
|
|
48
|
+
return (0, firebase_firestore.onSnapshot)((0, firebase_firestore.collection)(database, collectionPath), (snapshot) => {
|
|
49
|
+
const initial = !seen;
|
|
50
|
+
seen = true;
|
|
51
|
+
onChanged(snapshot.docChanges().map((change) => change.doc.id), { initial });
|
|
52
|
+
}, onError);
|
|
53
|
+
}
|
|
46
54
|
};
|
|
47
55
|
}
|
|
48
56
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firestore.cjs","names":[],"sources":["../../src/collection/server/firestoreDocs.ts"],"sourcesContent":["// The seam between the firestore store and the Firestore SDK.\n//\n// The modular SDK is function-based (`getDocs(query(collection(db, …)))`), so a\n// store that imported those functions directly could not be tested without a\n// real backend — a fake `db` would still be handed to the real functions.\n// Narrowing to this interface makes the backend swappable: core ships\n// `createFirestoreDocs` over the real SDK, and the tests inject an in-memory\n// fake that satisfies the same shape. That is what lets this repository's tests\n// run with no API key and no network.\n//\n// Deliberately minimal and id-keyed: no query builder, no field ordering, no\n// cursors. Everything the store needs is \"the documents of one collection path,\n// ordered by document id\" — see the store header for why field ordering is\n// avoided entirely.\n//\n// The collection path is an ARGUMENT, not something this module composes. It\n// owns the SDK calls; `firestoreStore` owns where the documents live.\n\nimport {\n collection as firestoreCollection,\n doc,\n getDoc,\n getDocs,\n orderBy,\n query as firestoreQuery,\n runTransaction,\n setDoc,\n type Firestore,\n} from \"firebase/firestore\";\n\n/** One stored record document. `data` is the document's own fields — the\n * record itself, not a wrapper around it; see `set` below. The store\n * validates its shape, because a document written by hand could be\n * anything. */\nexport interface FirestoreDoc {\n id: string;\n data: unknown;\n}\n\nexport interface FirestoreDocs {\n /** Every document under `collectionPath`, ordered by document id. */\n list: (collectionPath: string) => Promise<FirestoreDoc[]>;\n /** One document's fields, or null when it doesn't exist. */\n get: (collectionPath: string, docId: string) => Promise<unknown | null>;\n /** Create or replace. */\n set: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<void>;\n /** Create only. Returns false when the id already exists — atomic, so two\n * concurrent creates can't both observe \"missing\". */\n create: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<boolean>;\n /** Delete. Returns false when the id didn't exist, so a caller can tell a\n * real delete from a typo'd id. */\n delete: (collectionPath: string, docId: string) => Promise<boolean>;\n}\n\n/** The real implementation over the modular SDK.\n *\n * THE RECORD IS THE DOCUMENT. Its fields are written at the top level, not\n * nested under a `data` key. This is not a matter of taste: the deployed\n * security rules read `request.resource.data.<field>` and\n * `resource.data[submit.emailField]` — a wrapper would put every field one\n * level down, so the required-field checks, the status state machine and the\n * \"your own row\" predicate would all read absent values and fail closed. A\n * shared record's shape is part of the authorization contract.\n *\n * `orderBy(\"__name__\")` orders by DOCUMENT ID. Ordering by a record field\n * would silently EXCLUDE documents missing that field (the trap\n * `remote-host/server/hostRunner.ts:158-169` documents), turning a read into a\n * partial one; the document id is always present and gives the stable order\n * the store contract requires. */\nexport function createFirestoreDocs(database: Firestore): FirestoreDocs {\n return {\n list: async (collectionPath) => {\n const snapshot = await getDocs(firestoreQuery(firestoreCollection(database, collectionPath), orderBy(\"__name__\")));\n return snapshot.docs.map((entry) => ({ id: entry.id, data: entry.data() }));\n },\n get: async (collectionPath, docId) => {\n const snapshot = await getDoc(doc(database, collectionPath, docId));\n return snapshot.exists() ? snapshot.data() : null;\n },\n set: async (collectionPath, docId, data) => {\n await setDoc(doc(database, collectionPath, docId), data);\n },\n create: (collectionPath, docId, data) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (existing.exists()) return false;\n transaction.set(ref, data);\n return true;\n }),\n // Firestore's deleteDoc succeeds on a missing document, so an existence\n // check is what makes \"deleted\" distinguishable from \"there was nothing\".\n // It runs INSIDE the transaction (like `create`): a plain get-then-delete\n // would report `true` for a document a concurrent client had already\n // removed, i.e. claim a delete this call never performed.\n delete: (collectionPath, docId) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (!existing.exists()) return false;\n transaction.delete(ref);\n return true;\n }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"firestore.cjs","names":[],"sources":["../../src/collection/server/firestoreDocs.ts"],"sourcesContent":["// The seam between the firestore store and the Firestore SDK.\n//\n// The modular SDK is function-based (`getDocs(query(collection(db, …)))`), so a\n// store that imported those functions directly could not be tested without a\n// real backend — a fake `db` would still be handed to the real functions.\n// Narrowing to this interface makes the backend swappable: core ships\n// `createFirestoreDocs` over the real SDK, and the tests inject an in-memory\n// fake that satisfies the same shape. That is what lets this repository's tests\n// run with no API key and no network.\n//\n// Deliberately minimal and id-keyed: no query builder, no field ordering, no\n// cursors. Everything the store needs is \"the documents of one collection path,\n// ordered by document id\" — see the store header for why field ordering is\n// avoided entirely.\n//\n// The collection path is an ARGUMENT, not something this module composes. It\n// owns the SDK calls; `firestoreStore` owns where the documents live.\n\nimport {\n collection as firestoreCollection,\n doc,\n getDoc,\n getDocs,\n orderBy,\n query as firestoreQuery,\n onSnapshot,\n runTransaction,\n setDoc,\n type Firestore,\n} from \"firebase/firestore\";\n\n/** One stored record document. `data` is the document's own fields — the\n * record itself, not a wrapper around it; see `set` below. The store\n * validates its shape, because a document written by hand could be\n * anything. */\nexport interface FirestoreDoc {\n id: string;\n data: unknown;\n}\n\nexport interface FirestoreDocs {\n /** Every document under `collectionPath`, ordered by document id. */\n list: (collectionPath: string) => Promise<FirestoreDoc[]>;\n /** One document's fields, or null when it doesn't exist. */\n get: (collectionPath: string, docId: string) => Promise<unknown | null>;\n /** Create or replace. */\n set: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<void>;\n /** Create only. Returns false when the id already exists — atomic, so two\n * concurrent creates can't both observe \"missing\". */\n create: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<boolean>;\n /** Delete. Returns false when the id didn't exist, so a caller can tell a\n * real delete from a typo'd id. */\n delete: (collectionPath: string, docId: string) => Promise<boolean>;\n /** Listen to `collectionPath`. Every snapshot reports the ids that changed\n * in it, and whether it is the FIRST one.\n *\n * `initial` is not a nicety. `onSnapshot` delivers the current contents\n * immediately, as one snapshot in which every existing document reads as\n * `added` — so a listener that treats snapshots uniformly announces the\n * whole collection as changed the moment it arms, on every mount. The flag\n * is passed up rather than swallowed here so the decision (and its test)\n * lives with the store's policy, next to the rest of it.\n *\n * `onError` fires at most once per subscription: a Firestore listen error\n * TERMINATES the listener and never recovers on its own. Re-subscribing is\n * the caller's job (`firestore/listen.ts` holds the policy).\n *\n * Returns the detach function synchronously — `onSnapshot` is not async. */\n watch: (collectionPath: string, onChanged: (ids: string[], meta: { initial: boolean }) => void, onError: (error: unknown) => void) => () => void;\n}\n\n/** The real implementation over the modular SDK.\n *\n * THE RECORD IS THE DOCUMENT. Its fields are written at the top level, not\n * nested under a `data` key. This is not a matter of taste: the deployed\n * security rules read `request.resource.data.<field>` and\n * `resource.data[submit.emailField]` — a wrapper would put every field one\n * level down, so the required-field checks, the status state machine and the\n * \"your own row\" predicate would all read absent values and fail closed. A\n * shared record's shape is part of the authorization contract.\n *\n * `orderBy(\"__name__\")` orders by DOCUMENT ID. Ordering by a record field\n * would silently EXCLUDE documents missing that field (the trap\n * `remote-host/server/hostRunner.ts:158-169` documents), turning a read into a\n * partial one; the document id is always present and gives the stable order\n * the store contract requires. */\nexport function createFirestoreDocs(database: Firestore): FirestoreDocs {\n return {\n list: async (collectionPath) => {\n const snapshot = await getDocs(firestoreQuery(firestoreCollection(database, collectionPath), orderBy(\"__name__\")));\n return snapshot.docs.map((entry) => ({ id: entry.id, data: entry.data() }));\n },\n get: async (collectionPath, docId) => {\n const snapshot = await getDoc(doc(database, collectionPath, docId));\n return snapshot.exists() ? snapshot.data() : null;\n },\n set: async (collectionPath, docId, data) => {\n await setDoc(doc(database, collectionPath, docId), data);\n },\n create: (collectionPath, docId, data) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (existing.exists()) return false;\n transaction.set(ref, data);\n return true;\n }),\n // Firestore's deleteDoc succeeds on a missing document, so an existence\n // check is what makes \"deleted\" distinguishable from \"there was nothing\".\n // It runs INSIDE the transaction (like `create`): a plain get-then-delete\n // would report `true` for a document a concurrent client had already\n // removed, i.e. claim a delete this call never performed.\n delete: (collectionPath, docId) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (!existing.exists()) return false;\n transaction.delete(ref);\n return true;\n }),\n // `docChanges()` rather than the whole snapshot: it names the documents\n // that moved, which is what lets the store report per-record changes\n // instead of \"something in this collection changed\". Added, modified and\n // removed are all reported the same way — the store's listener takes an\n // id, and re-reads; what KIND of change it was is not something a\n // reconcile pass needs to be told.\n //\n // `includeMetadataChanges` is deliberately left off: local writes and\n // has-pending-writes flips would otherwise wake every listener for\n // changes this process just made.\n watch: (collectionPath, onChanged, onError) => {\n let seen = false;\n return onSnapshot(\n firestoreCollection(database, collectionPath),\n (snapshot) => {\n const initial = !seen;\n seen = true;\n onChanged(\n snapshot.docChanges().map((change) => change.doc.id),\n { initial },\n );\n },\n onError,\n );\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsFA,SAAgB,oBAAoB,UAAoC;CACtE,OAAO;EACL,MAAM,OAAO,mBAAmB;GAE9B,QAAO,OAAA,GADgB,mBAAA,QAAA,EAAA,GAAQ,mBAAA,MAAA,EAAA,GAAe,mBAAA,WAAA,CAAoB,UAAU,cAAc,IAAA,GAAG,mBAAA,QAAA,CAAQ,UAAU,CAAC,CAAC,EAAA,CACjG,KAAK,KAAK,WAAW;IAAE,IAAI,MAAM;IAAI,MAAM,MAAM,KAAK;GAAE,EAAE;EAC5E;EACA,KAAK,OAAO,gBAAgB,UAAU;GACpC,MAAM,WAAW,OAAA,GAAM,mBAAA,OAAA,EAAA,GAAO,mBAAA,IAAA,CAAI,UAAU,gBAAgB,KAAK,CAAC;GAClE,OAAO,SAAS,OAAO,IAAI,SAAS,KAAK,IAAI;EAC/C;EACA,KAAK,OAAO,gBAAgB,OAAO,SAAS;GAC1C,OAAA,GAAM,mBAAA,OAAA,EAAA,GAAO,mBAAA,IAAA,CAAI,UAAU,gBAAgB,KAAK,GAAG,IAAI;EACzD;EACA,SAAS,gBAAgB,OAAO,UAAA,GAC9B,mBAAA,eAAA,CAAe,UAAU,OAAO,gBAAgB;GAC9C,MAAM,OAAA,GAAM,mBAAA,IAAA,CAAI,UAAU,gBAAgB,KAAK;GAE/C,KAAI,MADmB,YAAY,IAAI,GAAG,EAAA,CAC7B,OAAO,GAAG,OAAO;GAC9B,YAAY,IAAI,KAAK,IAAI;GACzB,OAAO;EACT,CAAC;EAMH,SAAS,gBAAgB,WAAA,GACvB,mBAAA,eAAA,CAAe,UAAU,OAAO,gBAAgB;GAC9C,MAAM,OAAA,GAAM,mBAAA,IAAA,CAAI,UAAU,gBAAgB,KAAK;GAE/C,IAAI,EAAC,MADkB,YAAY,IAAI,GAAG,EAAA,CAC5B,OAAO,GAAG,OAAO;GAC/B,YAAY,OAAO,GAAG;GACtB,OAAO;EACT,CAAC;EAWH,QAAQ,gBAAgB,WAAW,YAAY;GAC7C,IAAI,OAAO;GACX,QAAA,GAAO,mBAAA,WAAA,EAAA,GACL,mBAAA,WAAA,CAAoB,UAAU,cAAc,IAC3C,aAAa;IACZ,MAAM,UAAU,CAAC;IACjB,OAAO;IACP,UACE,SAAS,WAAW,CAAC,CAAC,KAAK,WAAW,OAAO,IAAI,EAAE,GACnD,EAAE,QAAQ,CACZ;GACF,GACA,OACF;EACF;CACF;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { collection, doc, getDoc, getDocs, orderBy, query, runTransaction, setDoc } from "firebase/firestore";
|
|
1
|
+
import { collection, doc, getDoc, getDocs, onSnapshot, orderBy, query, runTransaction, setDoc } from "firebase/firestore";
|
|
2
2
|
//#region src/collection/server/firestoreDocs.ts
|
|
3
3
|
/** The real implementation over the modular SDK.
|
|
4
4
|
*
|
|
@@ -41,7 +41,15 @@ function createFirestoreDocs(database) {
|
|
|
41
41
|
if (!(await transaction.get(ref)).exists()) return false;
|
|
42
42
|
transaction.delete(ref);
|
|
43
43
|
return true;
|
|
44
|
-
})
|
|
44
|
+
}),
|
|
45
|
+
watch: (collectionPath, onChanged, onError) => {
|
|
46
|
+
let seen = false;
|
|
47
|
+
return onSnapshot(collection(database, collectionPath), (snapshot) => {
|
|
48
|
+
const initial = !seen;
|
|
49
|
+
seen = true;
|
|
50
|
+
onChanged(snapshot.docChanges().map((change) => change.doc.id), { initial });
|
|
51
|
+
}, onError);
|
|
52
|
+
}
|
|
45
53
|
};
|
|
46
54
|
}
|
|
47
55
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"firestore.js","names":[],"sources":["../../src/collection/server/firestoreDocs.ts"],"sourcesContent":["// The seam between the firestore store and the Firestore SDK.\n//\n// The modular SDK is function-based (`getDocs(query(collection(db, …)))`), so a\n// store that imported those functions directly could not be tested without a\n// real backend — a fake `db` would still be handed to the real functions.\n// Narrowing to this interface makes the backend swappable: core ships\n// `createFirestoreDocs` over the real SDK, and the tests inject an in-memory\n// fake that satisfies the same shape. That is what lets this repository's tests\n// run with no API key and no network.\n//\n// Deliberately minimal and id-keyed: no query builder, no field ordering, no\n// cursors. Everything the store needs is \"the documents of one collection path,\n// ordered by document id\" — see the store header for why field ordering is\n// avoided entirely.\n//\n// The collection path is an ARGUMENT, not something this module composes. It\n// owns the SDK calls; `firestoreStore` owns where the documents live.\n\nimport {\n collection as firestoreCollection,\n doc,\n getDoc,\n getDocs,\n orderBy,\n query as firestoreQuery,\n runTransaction,\n setDoc,\n type Firestore,\n} from \"firebase/firestore\";\n\n/** One stored record document. `data` is the document's own fields — the\n * record itself, not a wrapper around it; see `set` below. The store\n * validates its shape, because a document written by hand could be\n * anything. */\nexport interface FirestoreDoc {\n id: string;\n data: unknown;\n}\n\nexport interface FirestoreDocs {\n /** Every document under `collectionPath`, ordered by document id. */\n list: (collectionPath: string) => Promise<FirestoreDoc[]>;\n /** One document's fields, or null when it doesn't exist. */\n get: (collectionPath: string, docId: string) => Promise<unknown | null>;\n /** Create or replace. */\n set: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<void>;\n /** Create only. Returns false when the id already exists — atomic, so two\n * concurrent creates can't both observe \"missing\". */\n create: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<boolean>;\n /** Delete. Returns false when the id didn't exist, so a caller can tell a\n * real delete from a typo'd id. */\n delete: (collectionPath: string, docId: string) => Promise<boolean>;\n}\n\n/** The real implementation over the modular SDK.\n *\n * THE RECORD IS THE DOCUMENT. Its fields are written at the top level, not\n * nested under a `data` key. This is not a matter of taste: the deployed\n * security rules read `request.resource.data.<field>` and\n * `resource.data[submit.emailField]` — a wrapper would put every field one\n * level down, so the required-field checks, the status state machine and the\n * \"your own row\" predicate would all read absent values and fail closed. A\n * shared record's shape is part of the authorization contract.\n *\n * `orderBy(\"__name__\")` orders by DOCUMENT ID. Ordering by a record field\n * would silently EXCLUDE documents missing that field (the trap\n * `remote-host/server/hostRunner.ts:158-169` documents), turning a read into a\n * partial one; the document id is always present and gives the stable order\n * the store contract requires. */\nexport function createFirestoreDocs(database: Firestore): FirestoreDocs {\n return {\n list: async (collectionPath) => {\n const snapshot = await getDocs(firestoreQuery(firestoreCollection(database, collectionPath), orderBy(\"__name__\")));\n return snapshot.docs.map((entry) => ({ id: entry.id, data: entry.data() }));\n },\n get: async (collectionPath, docId) => {\n const snapshot = await getDoc(doc(database, collectionPath, docId));\n return snapshot.exists() ? snapshot.data() : null;\n },\n set: async (collectionPath, docId, data) => {\n await setDoc(doc(database, collectionPath, docId), data);\n },\n create: (collectionPath, docId, data) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (existing.exists()) return false;\n transaction.set(ref, data);\n return true;\n }),\n // Firestore's deleteDoc succeeds on a missing document, so an existence\n // check is what makes \"deleted\" distinguishable from \"there was nothing\".\n // It runs INSIDE the transaction (like `create`): a plain get-then-delete\n // would report `true` for a document a concurrent client had already\n // removed, i.e. claim a delete this call never performed.\n delete: (collectionPath, docId) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (!existing.exists()) return false;\n transaction.delete(ref);\n return true;\n }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"firestore.js","names":[],"sources":["../../src/collection/server/firestoreDocs.ts"],"sourcesContent":["// The seam between the firestore store and the Firestore SDK.\n//\n// The modular SDK is function-based (`getDocs(query(collection(db, …)))`), so a\n// store that imported those functions directly could not be tested without a\n// real backend — a fake `db` would still be handed to the real functions.\n// Narrowing to this interface makes the backend swappable: core ships\n// `createFirestoreDocs` over the real SDK, and the tests inject an in-memory\n// fake that satisfies the same shape. That is what lets this repository's tests\n// run with no API key and no network.\n//\n// Deliberately minimal and id-keyed: no query builder, no field ordering, no\n// cursors. Everything the store needs is \"the documents of one collection path,\n// ordered by document id\" — see the store header for why field ordering is\n// avoided entirely.\n//\n// The collection path is an ARGUMENT, not something this module composes. It\n// owns the SDK calls; `firestoreStore` owns where the documents live.\n\nimport {\n collection as firestoreCollection,\n doc,\n getDoc,\n getDocs,\n orderBy,\n query as firestoreQuery,\n onSnapshot,\n runTransaction,\n setDoc,\n type Firestore,\n} from \"firebase/firestore\";\n\n/** One stored record document. `data` is the document's own fields — the\n * record itself, not a wrapper around it; see `set` below. The store\n * validates its shape, because a document written by hand could be\n * anything. */\nexport interface FirestoreDoc {\n id: string;\n data: unknown;\n}\n\nexport interface FirestoreDocs {\n /** Every document under `collectionPath`, ordered by document id. */\n list: (collectionPath: string) => Promise<FirestoreDoc[]>;\n /** One document's fields, or null when it doesn't exist. */\n get: (collectionPath: string, docId: string) => Promise<unknown | null>;\n /** Create or replace. */\n set: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<void>;\n /** Create only. Returns false when the id already exists — atomic, so two\n * concurrent creates can't both observe \"missing\". */\n create: (collectionPath: string, docId: string, data: Record<string, unknown>) => Promise<boolean>;\n /** Delete. Returns false when the id didn't exist, so a caller can tell a\n * real delete from a typo'd id. */\n delete: (collectionPath: string, docId: string) => Promise<boolean>;\n /** Listen to `collectionPath`. Every snapshot reports the ids that changed\n * in it, and whether it is the FIRST one.\n *\n * `initial` is not a nicety. `onSnapshot` delivers the current contents\n * immediately, as one snapshot in which every existing document reads as\n * `added` — so a listener that treats snapshots uniformly announces the\n * whole collection as changed the moment it arms, on every mount. The flag\n * is passed up rather than swallowed here so the decision (and its test)\n * lives with the store's policy, next to the rest of it.\n *\n * `onError` fires at most once per subscription: a Firestore listen error\n * TERMINATES the listener and never recovers on its own. Re-subscribing is\n * the caller's job (`firestore/listen.ts` holds the policy).\n *\n * Returns the detach function synchronously — `onSnapshot` is not async. */\n watch: (collectionPath: string, onChanged: (ids: string[], meta: { initial: boolean }) => void, onError: (error: unknown) => void) => () => void;\n}\n\n/** The real implementation over the modular SDK.\n *\n * THE RECORD IS THE DOCUMENT. Its fields are written at the top level, not\n * nested under a `data` key. This is not a matter of taste: the deployed\n * security rules read `request.resource.data.<field>` and\n * `resource.data[submit.emailField]` — a wrapper would put every field one\n * level down, so the required-field checks, the status state machine and the\n * \"your own row\" predicate would all read absent values and fail closed. A\n * shared record's shape is part of the authorization contract.\n *\n * `orderBy(\"__name__\")` orders by DOCUMENT ID. Ordering by a record field\n * would silently EXCLUDE documents missing that field (the trap\n * `remote-host/server/hostRunner.ts:158-169` documents), turning a read into a\n * partial one; the document id is always present and gives the stable order\n * the store contract requires. */\nexport function createFirestoreDocs(database: Firestore): FirestoreDocs {\n return {\n list: async (collectionPath) => {\n const snapshot = await getDocs(firestoreQuery(firestoreCollection(database, collectionPath), orderBy(\"__name__\")));\n return snapshot.docs.map((entry) => ({ id: entry.id, data: entry.data() }));\n },\n get: async (collectionPath, docId) => {\n const snapshot = await getDoc(doc(database, collectionPath, docId));\n return snapshot.exists() ? snapshot.data() : null;\n },\n set: async (collectionPath, docId, data) => {\n await setDoc(doc(database, collectionPath, docId), data);\n },\n create: (collectionPath, docId, data) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (existing.exists()) return false;\n transaction.set(ref, data);\n return true;\n }),\n // Firestore's deleteDoc succeeds on a missing document, so an existence\n // check is what makes \"deleted\" distinguishable from \"there was nothing\".\n // It runs INSIDE the transaction (like `create`): a plain get-then-delete\n // would report `true` for a document a concurrent client had already\n // removed, i.e. claim a delete this call never performed.\n delete: (collectionPath, docId) =>\n runTransaction(database, async (transaction) => {\n const ref = doc(database, collectionPath, docId);\n const existing = await transaction.get(ref);\n if (!existing.exists()) return false;\n transaction.delete(ref);\n return true;\n }),\n // `docChanges()` rather than the whole snapshot: it names the documents\n // that moved, which is what lets the store report per-record changes\n // instead of \"something in this collection changed\". Added, modified and\n // removed are all reported the same way — the store's listener takes an\n // id, and re-reads; what KIND of change it was is not something a\n // reconcile pass needs to be told.\n //\n // `includeMetadataChanges` is deliberately left off: local writes and\n // has-pending-writes flips would otherwise wake every listener for\n // changes this process just made.\n watch: (collectionPath, onChanged, onError) => {\n let seen = false;\n return onSnapshot(\n firestoreCollection(database, collectionPath),\n (snapshot) => {\n const initial = !seen;\n seen = true;\n onChanged(\n snapshot.docChanges().map((change) => change.doc.id),\n { initial },\n );\n },\n onError,\n );\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAsFA,SAAgB,oBAAoB,UAAoC;CACtE,OAAO;EACL,MAAM,OAAO,mBAAmB;GAE9B,QAAO,MADgB,QAAQ,MAAe,WAAoB,UAAU,cAAc,GAAG,QAAQ,UAAU,CAAC,CAAC,EAAA,CACjG,KAAK,KAAK,WAAW;IAAE,IAAI,MAAM;IAAI,MAAM,MAAM,KAAK;GAAE,EAAE;EAC5E;EACA,KAAK,OAAO,gBAAgB,UAAU;GACpC,MAAM,WAAW,MAAM,OAAO,IAAI,UAAU,gBAAgB,KAAK,CAAC;GAClE,OAAO,SAAS,OAAO,IAAI,SAAS,KAAK,IAAI;EAC/C;EACA,KAAK,OAAO,gBAAgB,OAAO,SAAS;GAC1C,MAAM,OAAO,IAAI,UAAU,gBAAgB,KAAK,GAAG,IAAI;EACzD;EACA,SAAS,gBAAgB,OAAO,SAC9B,eAAe,UAAU,OAAO,gBAAgB;GAC9C,MAAM,MAAM,IAAI,UAAU,gBAAgB,KAAK;GAE/C,KAAI,MADmB,YAAY,IAAI,GAAG,EAAA,CAC7B,OAAO,GAAG,OAAO;GAC9B,YAAY,IAAI,KAAK,IAAI;GACzB,OAAO;EACT,CAAC;EAMH,SAAS,gBAAgB,UACvB,eAAe,UAAU,OAAO,gBAAgB;GAC9C,MAAM,MAAM,IAAI,UAAU,gBAAgB,KAAK;GAE/C,IAAI,EAAC,MADkB,YAAY,IAAI,GAAG,EAAA,CAC5B,OAAO,GAAG,OAAO;GAC/B,YAAY,OAAO,GAAG;GACtB,OAAO;EACT,CAAC;EAWH,QAAQ,gBAAgB,WAAW,YAAY;GAC7C,IAAI,OAAO;GACX,OAAO,WACL,WAAoB,UAAU,cAAc,IAC3C,aAAa;IACZ,MAAM,UAAU,CAAC;IACjB,OAAO;IACP,UACE,SAAS,WAAW,CAAC,CAAC,KAAK,WAAW,OAAO,IAAI,EAAE,GACnD,EAAE,QAAQ,CACZ;GACF,GACA,OACF;EACF;CACF;AACF"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_dist = require("../dist-CsgSfWwR.cjs");
|
|
3
|
-
const
|
|
3
|
+
const require_itemId = require("../itemId-Dzrr3vs5.cjs");
|
|
4
4
|
const require_project = require("../project-C1ep9pvo.cjs");
|
|
5
|
-
const require_promptSafety = require("../promptSafety-
|
|
5
|
+
const require_promptSafety = require("../promptSafety-CWqYq-NS.cjs");
|
|
6
6
|
//#region src/collection/core/presentCollection.ts
|
|
7
7
|
var TOOL_NAME = "presentCollection";
|
|
8
8
|
/** Stamp a host's opaque project scope onto a card payload. The ONLY way a
|
|
@@ -174,7 +174,7 @@ function enumColorClasses(index) {
|
|
|
174
174
|
/** Index of `value` within an enum field's declared `values`, or -1 when the
|
|
175
175
|
* value is empty / unknown (→ neutral). */
|
|
176
176
|
function enumValueIndex(values, value) {
|
|
177
|
-
const text =
|
|
177
|
+
const text = require_itemId.fieldTextOrNull(value);
|
|
178
178
|
if (text === null || text === "") return -1;
|
|
179
179
|
return values?.indexOf(text) ?? -1;
|
|
180
180
|
}
|
|
@@ -192,7 +192,7 @@ function notifyValuesFor(schema, fieldKey) {
|
|
|
192
192
|
function resolveEnumColor(schema, fieldKey, value) {
|
|
193
193
|
const notifyValues = notifyValuesFor(schema, fieldKey);
|
|
194
194
|
if (notifyValues) {
|
|
195
|
-
const str =
|
|
195
|
+
const str = require_itemId.fieldText(value);
|
|
196
196
|
const rank = notifyValues.indexOf(str);
|
|
197
197
|
if (rank < 0) return ENUM_NEUTRAL;
|
|
198
198
|
return rank === 0 ? ENUM_ALERT : ENUM_NUDGE;
|
|
@@ -218,7 +218,7 @@ function buildTableRowDraft(subFields, readSub) {
|
|
|
218
218
|
bool[subKey] = raw === true;
|
|
219
219
|
boolOriginallyPresent[subKey] = typeof raw === "boolean";
|
|
220
220
|
boolTouched[subKey] = false;
|
|
221
|
-
} else text[subKey] =
|
|
221
|
+
} else text[subKey] = require_itemId.fieldText(raw);
|
|
222
222
|
}
|
|
223
223
|
return {
|
|
224
224
|
text,
|
|
@@ -273,7 +273,7 @@ function rowDraftToRecord(rowDraft, subFields) {
|
|
|
273
273
|
function draftToRecord(state, schema) {
|
|
274
274
|
const record = {};
|
|
275
275
|
for (const [key, field] of Object.entries(schema.fields)) {
|
|
276
|
-
if (
|
|
276
|
+
if (require_itemId.COMPUTED_TYPES.has(field.type)) continue;
|
|
277
277
|
if (field.type === "boolean") {
|
|
278
278
|
if (shouldEmitBoolean(state, key, field)) record[key] = ownFlag(state.bool, key);
|
|
279
279
|
continue;
|
|
@@ -326,7 +326,7 @@ function firstMissingTableSubField(field, rows) {
|
|
|
326
326
|
* value, and the computed/projected kinds (COMPUTED_TYPES — the shared
|
|
327
327
|
* set, so a future computed type can't drift past this check) have no
|
|
328
328
|
* draft input at all. */
|
|
329
|
-
var NEVER_MISSING_TYPES = /* @__PURE__ */ new Set(["boolean", ...
|
|
329
|
+
var NEVER_MISSING_TYPES = /* @__PURE__ */ new Set(["boolean", ...require_itemId.COMPUTED_TYPES]);
|
|
330
330
|
function validateOneField(key, field, draft, record) {
|
|
331
331
|
if (!require_promptSafety.fieldVisible(field, record)) return null;
|
|
332
332
|
if (field.type === "table" && field.of) {
|
|
@@ -387,7 +387,7 @@ function numericSortValue(raw) {
|
|
|
387
387
|
} : EMPTY;
|
|
388
388
|
}
|
|
389
389
|
function stringSortValue(raw) {
|
|
390
|
-
const str =
|
|
390
|
+
const str = require_itemId.fieldTextOrNull(raw);
|
|
391
391
|
if (str === null) return EMPTY;
|
|
392
392
|
return str.trim() === "" ? EMPTY : {
|
|
393
393
|
empty: false,
|
|
@@ -395,7 +395,7 @@ function stringSortValue(raw) {
|
|
|
395
395
|
};
|
|
396
396
|
}
|
|
397
397
|
function dateSortValue(raw) {
|
|
398
|
-
const text =
|
|
398
|
+
const text = require_itemId.fieldTextOrNull(raw);
|
|
399
399
|
if (text === null || text === "") return EMPTY;
|
|
400
400
|
const epoch = Date.parse(text);
|
|
401
401
|
return Number.isNaN(epoch) ? stringSortValue(raw) : {
|
|
@@ -406,7 +406,7 @@ function dateSortValue(raw) {
|
|
|
406
406
|
/** Enum sorts by the value's index in the declared `values` list. A value
|
|
407
407
|
* outside the list (or unset) is treated as empty → last. */
|
|
408
408
|
function enumSortValue(values, raw) {
|
|
409
|
-
const text =
|
|
409
|
+
const text = require_itemId.fieldTextOrNull(raw);
|
|
410
410
|
if (text === null || text === "") return EMPTY;
|
|
411
411
|
const idx = values ? values.indexOf(text) : -1;
|
|
412
412
|
return idx < 0 ? EMPTY : {
|
|
@@ -491,7 +491,7 @@ function sortValueOf(field, key, item, deps) {
|
|
|
491
491
|
function itemMatchesQuery(item, query) {
|
|
492
492
|
if (query === "") return true;
|
|
493
493
|
return Object.values(item).some((value) => {
|
|
494
|
-
const text =
|
|
494
|
+
const text = require_itemId.fieldTextOrNull(value);
|
|
495
495
|
return text !== null && text.toLowerCase().includes(query);
|
|
496
496
|
});
|
|
497
497
|
}
|
|
@@ -508,7 +508,7 @@ function cellKey(rowId, fieldKey) {
|
|
|
508
508
|
* empty-enum snapshot always agree. A real primary key is a scalar, so this
|
|
509
509
|
* matches its plain string form. */
|
|
510
510
|
function rowIdOf(primaryKey, item) {
|
|
511
|
-
return primaryKey ?
|
|
511
|
+
return primaryKey ? require_itemId.fieldText(item[primaryKey]) : "";
|
|
512
512
|
}
|
|
513
513
|
/** The set of enum cells that were empty in the freshly-fetched records — the
|
|
514
514
|
* only cells whose inline dropdown offers an empty option. */
|
|
@@ -517,7 +517,7 @@ function snapshotEmptyEnums(schema, records) {
|
|
|
517
517
|
const enumKeys = Object.entries(schema.fields).filter(([, field]) => field.type === "enum").map(([fieldKey]) => fieldKey);
|
|
518
518
|
if (enumKeys.length === 0) return empty;
|
|
519
519
|
for (const record of records) {
|
|
520
|
-
const recordId =
|
|
520
|
+
const recordId = require_itemId.fieldText(record[schema.primaryKey]);
|
|
521
521
|
for (const fieldKey of enumKeys) if (record[fieldKey] == null || record[fieldKey] === "") empty.add(cellKey(recordId, fieldKey));
|
|
522
522
|
}
|
|
523
523
|
return empty;
|
|
@@ -541,7 +541,7 @@ function labelFieldFor(schema) {
|
|
|
541
541
|
}
|
|
542
542
|
/** A record's primary-key value as a string. */
|
|
543
543
|
function itemIdOf(item, schema) {
|
|
544
|
-
return
|
|
544
|
+
return require_itemId.fieldText(item[schema.primaryKey]);
|
|
545
545
|
}
|
|
546
546
|
/** A record's display label: the resolved `labelField` value, else the
|
|
547
547
|
* primary key. Pass the result of `labelFieldFor(schema)` as `labelField`
|
|
@@ -557,18 +557,6 @@ function itemLabelOf(item, schema, labelField) {
|
|
|
557
557
|
return itemIdOf(item, schema);
|
|
558
558
|
}
|
|
559
559
|
//#endregion
|
|
560
|
-
//#region src/collection/core/shortHexId.ts
|
|
561
|
-
/**
|
|
562
|
-
* 8-char hex id — short, slug-safe, and editable. Produces the same id *shape*
|
|
563
|
-
* as the server's `generateItemId()` (8 hex chars) so a UI-created collection
|
|
564
|
-
* record looks like one the server would have generated for a form submitted
|
|
565
|
-
* with a blank primary key. The source of randomness differs (UUID-derived here
|
|
566
|
-
* vs `randomBytes` on the server); only the shape is intentionally shared.
|
|
567
|
-
*/
|
|
568
|
-
function shortHexId() {
|
|
569
|
-
return crypto.randomUUID().replace(/-/g, "").slice(0, 8);
|
|
570
|
-
}
|
|
571
|
-
//#endregion
|
|
572
560
|
//#region src/collection/core/ontologyGraph.ts
|
|
573
561
|
var isForwardKind = (kind) => kind === "ref" || kind === "embed";
|
|
574
562
|
/** Fold a reverse relation (`backlinks`/`rollup` declared on `owner`)
|
|
@@ -639,25 +627,25 @@ var buildOntologyGraph = (entries) => {
|
|
|
639
627
|
};
|
|
640
628
|
};
|
|
641
629
|
//#endregion
|
|
642
|
-
exports.AGENT_INGEST_KIND =
|
|
643
|
-
exports.COMPUTED_TYPES =
|
|
630
|
+
exports.AGENT_INGEST_KIND = require_itemId.AGENT_INGEST_KIND;
|
|
631
|
+
exports.COMPUTED_TYPES = require_itemId.COMPUTED_TYPES;
|
|
644
632
|
exports.ENUM_ALERT = ENUM_ALERT;
|
|
645
633
|
exports.ENUM_NEUTRAL = ENUM_NEUTRAL;
|
|
646
634
|
exports.ENUM_NUDGE = ENUM_NUDGE;
|
|
647
|
-
exports.FEED_SCHEDULES =
|
|
648
|
-
exports.INGEST_KINDS =
|
|
649
|
-
exports.MINUTES_PER_DAY =
|
|
650
|
-
exports.SAFE_RECORD_ID_PATTERN =
|
|
651
|
-
exports.SAFE_SLUG_PATTERN =
|
|
635
|
+
exports.FEED_SCHEDULES = require_itemId.FEED_SCHEDULES;
|
|
636
|
+
exports.INGEST_KINDS = require_itemId.INGEST_KINDS;
|
|
637
|
+
exports.MINUTES_PER_DAY = require_itemId.MINUTES_PER_DAY;
|
|
638
|
+
exports.SAFE_RECORD_ID_PATTERN = require_itemId.SAFE_RECORD_ID_PATTERN;
|
|
639
|
+
exports.SAFE_SLUG_PATTERN = require_itemId.SAFE_SLUG_PATTERN;
|
|
652
640
|
exports.TOOL_DEFINITION = TOOL_DEFINITION;
|
|
653
641
|
exports.TOOL_NAME = TOOL_NAME;
|
|
654
642
|
exports.actionVisible = require_promptSafety.actionVisible;
|
|
655
643
|
exports.agentActionRunKey = require_promptSafety.agentActionRunKey;
|
|
656
|
-
exports.assignLanes =
|
|
644
|
+
exports.assignLanes = require_itemId.assignLanes;
|
|
657
645
|
exports.backlinkRows = require_promptSafety.backlinkRows;
|
|
658
646
|
exports.boolSortValue = boolSortValue;
|
|
659
|
-
exports.bucketRecords =
|
|
660
|
-
exports.buildMonthGrid =
|
|
647
|
+
exports.bucketRecords = require_itemId.bucketRecords;
|
|
648
|
+
exports.buildMonthGrid = require_itemId.buildMonthGrid;
|
|
661
649
|
exports.buildOntologyGraph = buildOntologyGraph;
|
|
662
650
|
exports.buildUpdatedRecord = buildUpdatedRecord;
|
|
663
651
|
exports.cellKey = cellKey;
|
|
@@ -665,19 +653,19 @@ exports.chipMatches = require_promptSafety.chipMatches;
|
|
|
665
653
|
exports.coerceInlineValue = coerceInlineValue;
|
|
666
654
|
exports.coerceNumeric = require_promptSafety.coerceNumeric;
|
|
667
655
|
exports.collectionCardKey = collectionCardKey;
|
|
668
|
-
exports.collectionKeyId =
|
|
669
|
-
exports.collectionKeyName =
|
|
656
|
+
exports.collectionKeyId = require_itemId.collectionKeyId;
|
|
657
|
+
exports.collectionKeyName = require_itemId.collectionKeyName;
|
|
670
658
|
exports.compareSortValues = compareSortValues;
|
|
671
|
-
exports.compareYmd =
|
|
659
|
+
exports.compareYmd = require_itemId.compareYmd;
|
|
672
660
|
exports.completionCoveredByFieldChip = require_promptSafety.completionCoveredByFieldChip;
|
|
673
|
-
exports.dateOf =
|
|
661
|
+
exports.dateOf = require_itemId.dateOf;
|
|
674
662
|
exports.dateSortValue = dateSortValue;
|
|
675
|
-
exports.daySlice =
|
|
663
|
+
exports.daySlice = require_itemId.daySlice;
|
|
676
664
|
exports.defangForPrompt = require_promptSafety.defangForPrompt;
|
|
677
665
|
exports.deriveAll = require_promptSafety.deriveAll;
|
|
678
666
|
exports.derivedSortValue = derivedSortValue;
|
|
679
667
|
exports.draftToRecord = draftToRecord;
|
|
680
|
-
exports.embedTargetId =
|
|
668
|
+
exports.embedTargetId = require_itemId.embedTargetId;
|
|
681
669
|
exports.emptyRow = emptyRow;
|
|
682
670
|
exports.enumColorClasses = enumColorClasses;
|
|
683
671
|
exports.enumSortValue = enumSortValue;
|
|
@@ -685,40 +673,41 @@ exports.enumValueIndex = enumValueIndex;
|
|
|
685
673
|
exports.errorMessage = require_dist.errorMessage;
|
|
686
674
|
exports.evaluateDerived = require_promptSafety.evaluateDerived;
|
|
687
675
|
exports.executePresentCollection = executePresentCollection;
|
|
688
|
-
exports.fieldText =
|
|
689
|
-
exports.fieldTextOrNull =
|
|
676
|
+
exports.fieldText = require_itemId.fieldText;
|
|
677
|
+
exports.fieldTextOrNull = require_itemId.fieldTextOrNull;
|
|
690
678
|
exports.fieldVisible = require_promptSafety.fieldVisible;
|
|
691
679
|
exports.firstDateField = require_promptSafety.firstDateField;
|
|
692
680
|
exports.firstMissingRequiredField = firstMissingRequiredField;
|
|
693
681
|
exports.flagFieldValue = require_promptSafety.flagFieldValue;
|
|
694
|
-
exports.generateUniqueId =
|
|
695
|
-
exports.isFieldDrivenEvery =
|
|
696
|
-
exports.isLocalCollectionKey =
|
|
697
|
-
exports.isReadOnlySchema =
|
|
698
|
-
exports.isSafeRecordId =
|
|
699
|
-
exports.isSafeSlug =
|
|
700
|
-
exports.isSharedCollectionKey =
|
|
682
|
+
exports.generateUniqueId = require_itemId.generateUniqueId;
|
|
683
|
+
exports.isFieldDrivenEvery = require_itemId.isFieldDrivenEvery;
|
|
684
|
+
exports.isLocalCollectionKey = require_itemId.isLocalCollectionKey;
|
|
685
|
+
exports.isReadOnlySchema = require_itemId.isReadOnlySchema;
|
|
686
|
+
exports.isSafeRecordId = require_itemId.isSafeRecordId;
|
|
687
|
+
exports.isSafeSlug = require_itemId.isSafeSlug;
|
|
688
|
+
exports.isSharedCollectionKey = require_itemId.isSharedCollectionKey;
|
|
701
689
|
exports.isSortableField = isSortableField;
|
|
702
|
-
exports.isValidCollectionName =
|
|
690
|
+
exports.isValidCollectionName = require_itemId.isValidCollectionName;
|
|
703
691
|
exports.itemIdOf = itemIdOf;
|
|
704
692
|
exports.itemIsDone = require_promptSafety.itemIsDone;
|
|
705
693
|
exports.itemLabelOf = itemLabelOf;
|
|
706
694
|
exports.itemMatchesQuery = itemMatchesQuery;
|
|
707
695
|
exports.labelFieldFor = labelFieldFor;
|
|
708
|
-
exports.localCollectionKeyOf =
|
|
696
|
+
exports.localCollectionKeyOf = require_itemId.localCollectionKeyOf;
|
|
709
697
|
exports.matchesWhere = require_promptSafety.matchesWhere;
|
|
710
698
|
exports.mergeIntoExisting = require_project.mergeIntoExisting;
|
|
711
|
-
exports.monthAnchorDate =
|
|
699
|
+
exports.monthAnchorDate = require_itemId.monthAnchorDate;
|
|
700
|
+
exports.newItemId = require_itemId.newItemId;
|
|
712
701
|
exports.nextSortDirection = nextSortDirection;
|
|
713
|
-
exports.nextUniqueItemId =
|
|
702
|
+
exports.nextUniqueItemId = require_itemId.nextUniqueItemId;
|
|
714
703
|
exports.numericSortValue = numericSortValue;
|
|
715
|
-
exports.parseCollectionKeyId =
|
|
716
|
-
exports.parseIsoDate =
|
|
717
|
-
exports.parseIsoDateTime =
|
|
718
|
-
exports.parseTimeRange =
|
|
704
|
+
exports.parseCollectionKeyId = require_itemId.parseCollectionKeyId;
|
|
705
|
+
exports.parseIsoDate = require_itemId.parseIsoDate;
|
|
706
|
+
exports.parseIsoDateTime = require_itemId.parseIsoDateTime;
|
|
707
|
+
exports.parseTimeRange = require_itemId.parseTimeRange;
|
|
719
708
|
exports.projectBacklinkRow = require_promptSafety.projectBacklinkRow;
|
|
720
709
|
exports.projectRecordFields = require_project.projectRecordFields;
|
|
721
|
-
exports.recordSpan =
|
|
710
|
+
exports.recordSpan = require_itemId.recordSpan;
|
|
722
711
|
exports.resolveEnumColor = resolveEnumColor;
|
|
723
712
|
exports.resolveIcon = require_promptSafety.resolveIcon;
|
|
724
713
|
exports.resolveRowRefs = require_promptSafety.resolveRowRefs;
|
|
@@ -726,17 +715,17 @@ exports.rollupValue = require_promptSafety.rollupValue;
|
|
|
726
715
|
exports.rowFromItem = rowFromItem;
|
|
727
716
|
exports.rowIdOf = rowIdOf;
|
|
728
717
|
exports.sameCollectionCard = sameCollectionCard;
|
|
729
|
-
exports.sameCollectionKey =
|
|
718
|
+
exports.sameCollectionKey = require_itemId.sameCollectionKey;
|
|
730
719
|
exports.scalarSortValue = scalarSortValue;
|
|
731
720
|
exports.selectDynamicRecord = require_promptSafety.selectDynamicRecord;
|
|
732
|
-
exports.sharedCollectionKey =
|
|
733
|
-
exports.shortHexId = shortHexId;
|
|
721
|
+
exports.sharedCollectionKey = require_itemId.sharedCollectionKey;
|
|
722
|
+
exports.shortHexId = require_itemId.shortHexId;
|
|
734
723
|
exports.skillCommandSeed = skillCommandSeed;
|
|
735
724
|
exports.snapshotEmptyEnums = snapshotEmptyEnums;
|
|
736
725
|
exports.sortItems = sortItems;
|
|
737
726
|
exports.sortValueOf = sortValueOf;
|
|
738
|
-
exports.spanCoversDay =
|
|
739
|
-
exports.storageKindFor =
|
|
727
|
+
exports.spanCoversDay = require_itemId.spanCoversDay;
|
|
728
|
+
exports.storageKindFor = require_itemId.storageKindFor;
|
|
740
729
|
exports.stringSortValue = stringSortValue;
|
|
741
730
|
exports.toPresentCollectionData = toPresentCollectionData;
|
|
742
731
|
exports.toggleChecked = require_promptSafety.toggleChecked;
|
|
@@ -746,6 +735,6 @@ exports.uniqueRefTargets = require_promptSafety.uniqueRefTargets;
|
|
|
746
735
|
exports.viaMatches = require_promptSafety.viaMatches;
|
|
747
736
|
exports.whenMatches = require_promptSafety.whenMatches;
|
|
748
737
|
exports.withCardScope = withCardScope;
|
|
749
|
-
exports.ymdKey =
|
|
738
|
+
exports.ymdKey = require_itemId.ymdKey;
|
|
750
739
|
|
|
751
740
|
//# sourceMappingURL=index.cjs.map
|