@pol-studios/db 1.0.54 → 1.0.56
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/{DataLayerContext-C7cJtiO8.d.ts → DataLayerContext-BYZtDD0g.d.ts} +1 -1
- package/dist/auth/context.js +6 -4
- package/dist/auth/hooks.js +7 -5
- package/dist/auth/index.js +7 -5
- package/dist/{chunk-FIAXWEBK.js → chunk-4EO55YV2.js} +10 -7
- package/dist/chunk-4EO55YV2.js.map +1 -0
- package/dist/{chunk-DP3YEVSX.js → chunk-6SDH7M7J.js} +26 -10
- package/dist/chunk-6SDH7M7J.js.map +1 -0
- package/dist/{chunk-UJWETW36.js → chunk-AKIRHA4Q.js} +527 -418
- package/dist/chunk-AKIRHA4Q.js.map +1 -0
- package/dist/{chunk-2XS2PM62.js → chunk-DDL63KLQ.js} +388 -107
- package/dist/chunk-DDL63KLQ.js.map +1 -0
- package/dist/{chunk-YA6MUTA7.js → chunk-FI6JAD5G.js} +3 -3
- package/dist/{chunk-WQLIGVQR.js → chunk-GWYTROSD.js} +98 -1
- package/dist/chunk-GWYTROSD.js.map +1 -0
- package/dist/chunk-JOULSXOI.js +415 -0
- package/dist/chunk-JOULSXOI.js.map +1 -0
- package/dist/{chunk-OKYHI6JG.js → chunk-LF3V3ERS.js} +3 -3
- package/dist/{chunk-FMYXG4VN.js → chunk-MEBT5YHA.js} +2 -2
- package/dist/{chunk-BZSAPFFB.js → chunk-N4KK5G5T.js} +116 -18
- package/dist/chunk-N4KK5G5T.js.map +1 -0
- package/dist/chunk-QYAFI34Q.js +64 -0
- package/dist/chunk-QYAFI34Q.js.map +1 -0
- package/dist/{chunk-3Q74DK5K.js → chunk-VYFAMTHI.js} +2 -2
- package/dist/chunk-W7PERM66.js +215 -0
- package/dist/chunk-W7PERM66.js.map +1 -0
- package/dist/{chunk-ZGQ7Q4ZU.js → chunk-WM25QE7E.js} +2 -2
- package/dist/{chunk-HZIVE5AZ.js → chunk-YRIPM2AN.js} +253 -338
- package/dist/chunk-YRIPM2AN.js.map +1 -0
- package/dist/chunk-YUX6RGLZ.js +1858 -0
- package/dist/chunk-YUX6RGLZ.js.map +1 -0
- package/dist/{chunk-Z3EJX3VG.js → chunk-Z456IHCB.js} +3 -3
- package/dist/core/index.d.ts +24 -1
- package/dist/{executor-YJw4m7Q7.d.ts → executor-D15yjeMo.d.ts} +20 -0
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.js +4 -2
- package/dist/{index-jVYdTeWx.d.ts → index-CFUuTzXO.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +16 -14
- package/dist/index.native.d.ts +62 -8
- package/dist/index.native.js +16 -14
- package/dist/index.web.d.ts +10 -9
- package/dist/index.web.js +30 -19
- package/dist/index.web.js.map +1 -1
- package/dist/mutation/index.js +3 -3
- package/dist/parser/index.js +3 -3
- package/dist/powersync-bridge/index.d.ts +1 -1
- package/dist/query/index.d.ts +4 -83
- package/dist/query/index.js +17 -7
- package/dist/realtime/index.d.ts +80 -1
- package/dist/realtime/index.js +14 -12
- package/dist/realtime/index.js.map +1 -1
- package/dist/select-parser-BAV7fOaM.d.ts +144 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +4 -4
- package/dist/{useDbCount-DHLJzmkO.d.ts → useDbCount-Ckb-FhZk.d.ts} +1 -1
- package/dist/{useResolveFeedback-B0UcYWVI.d.ts → useResolveFeedback-CuUkdHoR.d.ts} +13 -29
- package/dist/with-auth/index.js +9 -7
- package/dist/with-auth/index.js.map +1 -1
- package/package.json +9 -4
- package/dist/chunk-2XS2PM62.js.map +0 -1
- package/dist/chunk-BZSAPFFB.js.map +0 -1
- package/dist/chunk-CTRY7JDP.js +0 -4112
- package/dist/chunk-CTRY7JDP.js.map +0 -1
- package/dist/chunk-DP3YEVSX.js.map +0 -1
- package/dist/chunk-FIAXWEBK.js.map +0 -1
- package/dist/chunk-HZIVE5AZ.js.map +0 -1
- package/dist/chunk-INEUG6MC.js +0 -521
- package/dist/chunk-INEUG6MC.js.map +0 -1
- package/dist/chunk-UJWETW36.js.map +0 -1
- package/dist/chunk-WQLIGVQR.js.map +0 -1
- /package/dist/{chunk-YA6MUTA7.js.map → chunk-FI6JAD5G.js.map} +0 -0
- /package/dist/{chunk-OKYHI6JG.js.map → chunk-LF3V3ERS.js.map} +0 -0
- /package/dist/{chunk-FMYXG4VN.js.map → chunk-MEBT5YHA.js.map} +0 -0
- /package/dist/{chunk-3Q74DK5K.js.map → chunk-VYFAMTHI.js.map} +0 -0
- /package/dist/{chunk-ZGQ7Q4ZU.js.map → chunk-WM25QE7E.js.map} +0 -0
- /package/dist/{chunk-Z3EJX3VG.js.map → chunk-Z456IHCB.js.map} +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// src/realtime/explicit-fk-merge.ts
|
|
2
|
+
function mergeRelatedUpdate(parentData, relation, changedRecords) {
|
|
3
|
+
const changedById = /* @__PURE__ */ new Map();
|
|
4
|
+
for (const record of changedRecords) {
|
|
5
|
+
if (record.id) {
|
|
6
|
+
changedById.set(record.id, record);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
if (changedById.size === 0) {
|
|
10
|
+
return parentData;
|
|
11
|
+
}
|
|
12
|
+
let hasChanges = false;
|
|
13
|
+
const updatedData = parentData.map((parent) => {
|
|
14
|
+
const fkValue = parent[relation.sourceField];
|
|
15
|
+
if (fkValue == null || typeof fkValue !== "string") {
|
|
16
|
+
return parent;
|
|
17
|
+
}
|
|
18
|
+
const changedRecord = changedById.get(fkValue);
|
|
19
|
+
if (!changedRecord) {
|
|
20
|
+
return parent;
|
|
21
|
+
}
|
|
22
|
+
const existingRelation = parent[relation.alias];
|
|
23
|
+
if (existingRelation == null || typeof existingRelation !== "object") {
|
|
24
|
+
return parent;
|
|
25
|
+
}
|
|
26
|
+
const mergedRelation = {
|
|
27
|
+
...existingRelation,
|
|
28
|
+
...changedRecord
|
|
29
|
+
};
|
|
30
|
+
hasChanges = true;
|
|
31
|
+
return {
|
|
32
|
+
...parent,
|
|
33
|
+
[relation.alias]: mergedRelation
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
return hasChanges ? updatedData : parentData;
|
|
37
|
+
}
|
|
38
|
+
function mergeSingleRelatedUpdate(parentData, relation, changedRecord) {
|
|
39
|
+
return mergeRelatedUpdate(parentData, relation, [changedRecord]);
|
|
40
|
+
}
|
|
41
|
+
function parentReferencesRelated(parentData, relation, relatedId) {
|
|
42
|
+
return parentData.some((parent) => {
|
|
43
|
+
const fkValue = parent[relation.sourceField];
|
|
44
|
+
return fkValue === relatedId;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function extractRelatedIds(parentData, relation) {
|
|
48
|
+
const ids = /* @__PURE__ */ new Set();
|
|
49
|
+
for (const parent of parentData) {
|
|
50
|
+
const fkValue = parent[relation.sourceField];
|
|
51
|
+
if (typeof fkValue === "string" && fkValue) {
|
|
52
|
+
ids.add(fkValue);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return ids;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export {
|
|
59
|
+
mergeRelatedUpdate,
|
|
60
|
+
mergeSingleRelatedUpdate,
|
|
61
|
+
parentReferencesRelated,
|
|
62
|
+
extractRelatedIds
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=chunk-QYAFI34Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/realtime/explicit-fk-merge.ts"],"sourcesContent":["/**\n * Optimistic Merge Utilities for Explicit FK Relations\n *\n * When using realtime subscriptions with explicit FK joins (e.g., Sender!senderId:core.Profile(*)),\n * changes to related tables need to be optimistically merged into cached query data.\n *\n * This module provides utilities for:\n * 1. Extracting explicit FK relation info from select strings\n * 2. Merging changes from related tables into parent query data\n * 3. Managing multiple subscriptions for related tables\n */\n\nimport type { ExtractedExplicitFk } from \"../query/select-parser\";\n\n/**\n * A changed record from a related table.\n */\nexport interface ChangedRecord {\n /** The record ID */\n id: string;\n /** All record fields */\n [key: string]: unknown;\n}\n\n/**\n * Merge updated related records into parent query data.\n *\n * When a record in a related table changes, this function updates all references\n * to that record within the parent data's nested relations.\n *\n * @param parentData - The current cached query data (array of parent records)\n * @param relation - The explicit FK relation info (alias, sourceField, etc.)\n * @param changedRecords - The updated records from the related table\n * @returns New array with merged updates (immutable - does not modify input)\n *\n * @example\n * // Parent data has: [{ id: \"1\", senderId: \"user-1\", Sender: { id: \"user-1\", name: \"Alice\" } }]\n * // User \"user-1\" changed their name to \"Bob\"\n * const updated = mergeRelatedUpdate(\n * parentData,\n * { alias: \"Sender\", sourceField: \"senderId\", targetTable: \"User\", targetColumn: \"id\" },\n * [{ id: \"user-1\", name: \"Bob\" }]\n * );\n * // Result: [{ id: \"1\", senderId: \"user-1\", Sender: { id: \"user-1\", name: \"Bob\" } }]\n */\nexport function mergeRelatedUpdate<T extends Record<string, unknown>>(parentData: T[], relation: ExtractedExplicitFk, changedRecords: ChangedRecord[]): T[] {\n // Build a lookup map for changed records by ID\n const changedById = new Map<string, ChangedRecord>();\n for (const record of changedRecords) {\n if (record.id) {\n changedById.set(record.id, record);\n }\n }\n\n // If no records have IDs, nothing to merge\n if (changedById.size === 0) {\n return parentData;\n }\n let hasChanges = false;\n\n // Map over parent data, updating nested relations where needed\n const updatedData = parentData.map(parent => {\n // Get the foreign key value from the parent\n const fkValue = parent[relation.sourceField];\n if (fkValue == null || typeof fkValue !== \"string\") {\n return parent;\n }\n\n // Check if this FK references a changed record\n const changedRecord = changedById.get(fkValue);\n if (!changedRecord) {\n return parent;\n }\n\n // Get the existing nested relation data\n const existingRelation = parent[relation.alias];\n if (existingRelation == null || typeof existingRelation !== \"object\") {\n // No existing relation data to merge into - skip\n // (The relation might not have been selected in the original query)\n return parent;\n }\n\n // Merge the changed fields into the nested relation\n // Preserve existing fields that aren't in changedRecord\n const mergedRelation = {\n ...(existingRelation as Record<string, unknown>),\n ...changedRecord\n };\n hasChanges = true;\n\n // Return updated parent with merged relation\n return {\n ...parent,\n [relation.alias]: mergedRelation\n };\n });\n\n // Return original array if nothing changed (preserves reference equality)\n return hasChanges ? updatedData : parentData;\n}\n\n/**\n * Merge a single changed record into parent query data.\n *\n * Convenience wrapper around mergeRelatedUpdate for single record changes.\n *\n * @param parentData - The current cached query data\n * @param relation - The explicit FK relation info\n * @param changedRecord - The updated record from the related table\n * @returns New array with merged update\n */\nexport function mergeSingleRelatedUpdate<T extends Record<string, unknown>>(parentData: T[], relation: ExtractedExplicitFk, changedRecord: ChangedRecord): T[] {\n return mergeRelatedUpdate(parentData, relation, [changedRecord]);\n}\n\n/**\n * Check if any parent records reference a given related record ID.\n *\n * Useful for determining whether a change to a related record is relevant\n * to the current query data.\n *\n * @param parentData - The current cached query data\n * @param relation - The explicit FK relation info\n * @param relatedId - The ID of the related record that changed\n * @returns true if any parent references this related record\n */\nexport function parentReferencesRelated<T extends Record<string, unknown>>(parentData: T[], relation: ExtractedExplicitFk, relatedId: string): boolean {\n return parentData.some(parent => {\n const fkValue = parent[relation.sourceField];\n return fkValue === relatedId;\n });\n}\n\n/**\n * Extract all related IDs from parent data for a given relation.\n *\n * Useful for filtering realtime subscriptions to only watch relevant records.\n *\n * @param parentData - The current cached query data\n * @param relation - The explicit FK relation info\n * @returns Set of related record IDs referenced by the parent data\n */\nexport function extractRelatedIds<T extends Record<string, unknown>>(parentData: T[], relation: ExtractedExplicitFk): Set<string> {\n const ids = new Set<string>();\n for (const parent of parentData) {\n const fkValue = parent[relation.sourceField];\n if (typeof fkValue === \"string\" && fkValue) {\n ids.add(fkValue);\n }\n }\n return ids;\n}"],"mappings":";AA6CO,SAAS,mBAAsD,YAAiB,UAA+B,gBAAsC;AAE1J,QAAM,cAAc,oBAAI,IAA2B;AACnD,aAAW,UAAU,gBAAgB;AACnC,QAAI,OAAO,IAAI;AACb,kBAAY,IAAI,OAAO,IAAI,MAAM;AAAA,IACnC;AAAA,EACF;AAGA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,aAAa;AAGjB,QAAM,cAAc,WAAW,IAAI,YAAU;AAE3C,UAAM,UAAU,OAAO,SAAS,WAAW;AAC3C,QAAI,WAAW,QAAQ,OAAO,YAAY,UAAU;AAClD,aAAO;AAAA,IACT;AAGA,UAAM,gBAAgB,YAAY,IAAI,OAAO;AAC7C,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,IACT;AAGA,UAAM,mBAAmB,OAAO,SAAS,KAAK;AAC9C,QAAI,oBAAoB,QAAQ,OAAO,qBAAqB,UAAU;AAGpE,aAAO;AAAA,IACT;AAIA,UAAM,iBAAiB;AAAA,MACrB,GAAI;AAAA,MACJ,GAAG;AAAA,IACL;AACA,iBAAa;AAGb,WAAO;AAAA,MACL,GAAG;AAAA,MACH,CAAC,SAAS,KAAK,GAAG;AAAA,IACpB;AAAA,EACF,CAAC;AAGD,SAAO,aAAa,cAAc;AACpC;AAYO,SAAS,yBAA4D,YAAiB,UAA+B,eAAmC;AAC7J,SAAO,mBAAmB,YAAY,UAAU,CAAC,aAAa,CAAC;AACjE;AAaO,SAAS,wBAA2D,YAAiB,UAA+B,WAA4B;AACrJ,SAAO,WAAW,KAAK,YAAU;AAC/B,UAAM,UAAU,OAAO,SAAS,WAAW;AAC3C,WAAO,YAAY;AAAA,EACrB,CAAC;AACH;AAWO,SAAS,kBAAqD,YAAiB,UAA4C;AAChI,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,UAAU,YAAY;AAC/B,UAAM,UAAU,OAAO,SAAS,WAAW;AAC3C,QAAI,OAAO,YAAY,YAAY,SAAS;AAC1C,UAAI,IAAI,OAAO;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;","names":[]}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
useDataLayerCore,
|
|
7
7
|
useDataLayerStatus,
|
|
8
8
|
useDbQuery
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-GWYTROSD.js";
|
|
10
10
|
import {
|
|
11
11
|
getSupabaseUrl
|
|
12
12
|
} from "./chunk-GC3TBUWE.js";
|
|
@@ -1239,4 +1239,4 @@ export {
|
|
|
1239
1239
|
useSyncControl,
|
|
1240
1240
|
useOnlineStatus
|
|
1241
1241
|
};
|
|
1242
|
-
//# sourceMappingURL=chunk-
|
|
1242
|
+
//# sourceMappingURL=chunk-VYFAMTHI.js.map
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// src/query/select-parser.ts
|
|
2
|
+
function tokenizeTopLevel(input) {
|
|
3
|
+
const tokens = [];
|
|
4
|
+
let current = "";
|
|
5
|
+
let depth = 0;
|
|
6
|
+
for (const char of input) {
|
|
7
|
+
if (char === "(") {
|
|
8
|
+
depth++;
|
|
9
|
+
current += char;
|
|
10
|
+
} else if (char === ")") {
|
|
11
|
+
depth--;
|
|
12
|
+
current += char;
|
|
13
|
+
} else if (char === "," && depth === 0) {
|
|
14
|
+
const trimmed2 = current.trim();
|
|
15
|
+
if (trimmed2) {
|
|
16
|
+
tokens.push(trimmed2);
|
|
17
|
+
}
|
|
18
|
+
current = "";
|
|
19
|
+
} else {
|
|
20
|
+
current += char;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const trimmed = current.trim();
|
|
24
|
+
if (trimmed) {
|
|
25
|
+
tokens.push(trimmed);
|
|
26
|
+
}
|
|
27
|
+
return tokens;
|
|
28
|
+
}
|
|
29
|
+
function parseColumnToken(token) {
|
|
30
|
+
const aliasMatch = token.match(/^(\w+):(\w+)$/);
|
|
31
|
+
if (aliasMatch) {
|
|
32
|
+
return {
|
|
33
|
+
name: aliasMatch[2],
|
|
34
|
+
alias: aliasMatch[1]
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
name: token
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function parseSelect(select) {
|
|
42
|
+
const trimmed = select.trim();
|
|
43
|
+
if (trimmed === "*") {
|
|
44
|
+
return {
|
|
45
|
+
columns: "*",
|
|
46
|
+
relations: []
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (!trimmed) {
|
|
50
|
+
return {
|
|
51
|
+
columns: "*",
|
|
52
|
+
relations: []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const result = {
|
|
56
|
+
columns: [],
|
|
57
|
+
relations: []
|
|
58
|
+
};
|
|
59
|
+
const tokens = tokenizeTopLevel(trimmed);
|
|
60
|
+
for (const token of tokens) {
|
|
61
|
+
const trimmedToken = token.trim();
|
|
62
|
+
if (!trimmedToken) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const explicitFkMatch = trimmedToken.match(/^(\w+)!(\w+):([\w.]+)\((.+)\)$/);
|
|
66
|
+
if (explicitFkMatch) {
|
|
67
|
+
const [, alias, sourceField, targetTable, innerSelect] = explicitFkMatch;
|
|
68
|
+
const innerParsed = parseSelect(innerSelect);
|
|
69
|
+
result.relations.push({
|
|
70
|
+
name: targetTable,
|
|
71
|
+
// Use target table as the relation name
|
|
72
|
+
alias,
|
|
73
|
+
columns: innerParsed.columns,
|
|
74
|
+
relations: innerParsed.relations,
|
|
75
|
+
explicitFk: {
|
|
76
|
+
sourceField,
|
|
77
|
+
targetTable
|
|
78
|
+
// targetColumn defaults to "id" - handled at resolution time
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const relationMatch = trimmedToken.match(/^(?:(\w+):)?(\w+)\((.+)\)$/);
|
|
84
|
+
if (relationMatch) {
|
|
85
|
+
const alias = relationMatch[1];
|
|
86
|
+
const name = relationMatch[2];
|
|
87
|
+
const innerSelect = relationMatch[3];
|
|
88
|
+
const innerParsed = parseSelect(innerSelect);
|
|
89
|
+
result.relations.push({
|
|
90
|
+
name,
|
|
91
|
+
alias,
|
|
92
|
+
columns: innerParsed.columns,
|
|
93
|
+
relations: innerParsed.relations
|
|
94
|
+
});
|
|
95
|
+
} else if (trimmedToken === "*") {
|
|
96
|
+
result.columns = "*";
|
|
97
|
+
} else {
|
|
98
|
+
const column = parseColumnToken(trimmedToken);
|
|
99
|
+
if (result.columns !== "*") {
|
|
100
|
+
result.columns.push(column);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (Array.isArray(result.columns) && result.columns.length === 0) {
|
|
105
|
+
result.columns = "*";
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
function stringifySelect(parsed) {
|
|
110
|
+
const parts = [];
|
|
111
|
+
if (parsed.columns === "*") {
|
|
112
|
+
parts.push("*");
|
|
113
|
+
} else {
|
|
114
|
+
for (const col of parsed.columns) {
|
|
115
|
+
if (col.alias) {
|
|
116
|
+
parts.push(`${col.alias}:${col.name}`);
|
|
117
|
+
} else {
|
|
118
|
+
parts.push(col.name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const rel of parsed.relations) {
|
|
123
|
+
const innerStr = stringifySelect({
|
|
124
|
+
columns: rel.columns,
|
|
125
|
+
relations: rel.relations
|
|
126
|
+
});
|
|
127
|
+
if (rel.explicitFk) {
|
|
128
|
+
parts.push(`${rel.alias}!${rel.explicitFk.sourceField}:${rel.explicitFk.targetTable}(${innerStr})`);
|
|
129
|
+
} else if (rel.alias) {
|
|
130
|
+
parts.push(`${rel.alias}:${rel.name}(${innerStr})`);
|
|
131
|
+
} else {
|
|
132
|
+
parts.push(`${rel.name}(${innerStr})`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return parts.join(", ");
|
|
136
|
+
}
|
|
137
|
+
function extractColumnNames(parsed) {
|
|
138
|
+
if (parsed.columns === "*") {
|
|
139
|
+
return "*";
|
|
140
|
+
}
|
|
141
|
+
return parsed.columns.map((col) => col.name);
|
|
142
|
+
}
|
|
143
|
+
function extractRelationNames(parsed) {
|
|
144
|
+
return parsed.relations.map((rel) => rel.alias ?? rel.name);
|
|
145
|
+
}
|
|
146
|
+
function hasRelation(parsed, relationName) {
|
|
147
|
+
return parsed.relations.some((rel) => rel.name === relationName || rel.alias === relationName);
|
|
148
|
+
}
|
|
149
|
+
function getRelationSelect(parsed, relationName) {
|
|
150
|
+
return parsed.relations.find((rel) => rel.name === relationName || rel.alias === relationName);
|
|
151
|
+
}
|
|
152
|
+
function hasExplicitFk(parsed) {
|
|
153
|
+
for (const relation of parsed.relations) {
|
|
154
|
+
if (relation.explicitFk) {
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
if (relation.relations.length > 0 && hasExplicitFk({
|
|
158
|
+
columns: relation.columns,
|
|
159
|
+
relations: relation.relations
|
|
160
|
+
})) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
function selectHasExplicitFkSyntax(select) {
|
|
167
|
+
return /\w+!\w+:[\w.]+\(/.test(select);
|
|
168
|
+
}
|
|
169
|
+
function extractExplicitFkRelations(parsed) {
|
|
170
|
+
const results = [];
|
|
171
|
+
function collectFromRelations(relations) {
|
|
172
|
+
for (const relation of relations) {
|
|
173
|
+
if (relation.explicitFk) {
|
|
174
|
+
results.push({
|
|
175
|
+
alias: relation.alias ?? relation.name,
|
|
176
|
+
sourceField: relation.explicitFk.sourceField,
|
|
177
|
+
targetTable: relation.explicitFk.targetTable,
|
|
178
|
+
targetColumn: relation.explicitFk.targetColumn ?? "id"
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (relation.relations.length > 0) {
|
|
182
|
+
collectFromRelations(relation.relations);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
collectFromRelations(parsed.relations);
|
|
187
|
+
return results;
|
|
188
|
+
}
|
|
189
|
+
function extractExplicitFkTables(select) {
|
|
190
|
+
if (!selectHasExplicitFkSyntax(select)) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
const parsed = parseSelect(select);
|
|
194
|
+
const explicitFks = extractExplicitFkRelations(parsed);
|
|
195
|
+
const uniqueTables = /* @__PURE__ */ new Set();
|
|
196
|
+
for (const fk of explicitFks) {
|
|
197
|
+
uniqueTables.add(fk.targetTable);
|
|
198
|
+
}
|
|
199
|
+
return Array.from(uniqueTables);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export {
|
|
203
|
+
tokenizeTopLevel,
|
|
204
|
+
parseSelect,
|
|
205
|
+
stringifySelect,
|
|
206
|
+
extractColumnNames,
|
|
207
|
+
extractRelationNames,
|
|
208
|
+
hasRelation,
|
|
209
|
+
getRelationSelect,
|
|
210
|
+
hasExplicitFk,
|
|
211
|
+
selectHasExplicitFkSyntax,
|
|
212
|
+
extractExplicitFkRelations,
|
|
213
|
+
extractExplicitFkTables
|
|
214
|
+
};
|
|
215
|
+
//# sourceMappingURL=chunk-W7PERM66.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/query/select-parser.ts"],"sourcesContent":["/**\n * Select String Parser\n *\n * Parses Supabase PostgREST select syntax into an AST for local SQLite processing.\n *\n * Supported Syntax:\n * - \"*\" -> All columns\n * - \"id, name, status\" -> Specific columns\n * - \"*, RelatedTable(*)\" -> All columns + relation\n * - \"id, RelatedTable(id, name)\" -> Specific + relation with specific columns\n * - \"*, Parent(*, Grandparent(name))\" -> Nested relations\n * - \"*, items:RelatedTable(*)\" -> Aliased relation\n * - \"aliasName:columnName\" -> Aliased column\n */\n\nimport type { ParsedSelect, SelectColumn, SelectRelation } from \"../core/types\";\n\n/**\n * Tokenize a string at the top level, respecting parentheses nesting.\n * Splits by comma but keeps nested parentheses intact.\n *\n * @example\n * tokenizeTopLevel(\"id, name, Parent(*, Child(name))\")\n * // Returns: [\"id\", \"name\", \"Parent(*, Child(name))\"]\n */\nfunction tokenizeTopLevel(input: string): string[] {\n const tokens: string[] = [];\n let current = \"\";\n let depth = 0;\n for (const char of input) {\n if (char === \"(\") {\n depth++;\n current += char;\n } else if (char === \")\") {\n depth--;\n current += char;\n } else if (char === \",\" && depth === 0) {\n const trimmed = current.trim();\n if (trimmed) {\n tokens.push(trimmed);\n }\n current = \"\";\n } else {\n current += char;\n }\n }\n\n // Add the last token\n const trimmed = current.trim();\n if (trimmed) {\n tokens.push(trimmed);\n }\n return tokens;\n}\n\n/**\n * Parse a single column token that may have an alias.\n *\n * @example\n * parseColumnToken(\"aliasName:columnName\") -> { name: \"columnName\", alias: \"aliasName\" }\n * parseColumnToken(\"columnName\") -> { name: \"columnName\" }\n */\nfunction parseColumnToken(token: string): SelectColumn {\n // Check for alias format: alias:column\n const aliasMatch = token.match(/^(\\w+):(\\w+)$/);\n if (aliasMatch) {\n return {\n name: aliasMatch[2],\n alias: aliasMatch[1]\n };\n }\n return {\n name: token\n };\n}\n\n/**\n * Parse a Supabase PostgREST select string into an AST.\n *\n * @param select - The select string (e.g., \"*, RelatedTable(*)\")\n * @returns Parsed select AST\n *\n * @example\n * parseSelect(\"*\")\n * // Returns: { columns: \"*\", relations: [] }\n *\n * parseSelect(\"id, name, status\")\n * // Returns: {\n * // columns: [{ name: \"id\" }, { name: \"name\" }, { name: \"status\" }],\n * // relations: []\n * // }\n *\n * parseSelect(\"*, EquipmentFixture(*)\")\n * // Returns: {\n * // columns: \"*\",\n * // relations: [{ name: \"EquipmentFixture\", columns: \"*\", relations: [] }]\n * // }\n *\n * parseSelect(\"id, name, ProjectDatabase(name, Organization(*))\")\n * // Returns: {\n * // columns: [{ name: \"id\" }, { name: \"name\" }],\n * // relations: [{\n * // name: \"ProjectDatabase\",\n * // columns: [{ name: \"name\" }],\n * // relations: [{ name: \"Organization\", columns: \"*\", relations: [] }]\n * // }]\n * // }\n */\nexport function parseSelect(select: string): ParsedSelect {\n const trimmed = select.trim();\n\n // Handle simple wildcard\n if (trimmed === \"*\") {\n return {\n columns: \"*\",\n relations: []\n };\n }\n\n // Handle empty string\n if (!trimmed) {\n return {\n columns: \"*\",\n relations: []\n };\n }\n const result: ParsedSelect = {\n columns: [],\n relations: []\n };\n\n // Tokenize at top level (respecting parentheses)\n const tokens = tokenizeTopLevel(trimmed);\n for (const token of tokens) {\n const trimmedToken = token.trim();\n if (!trimmedToken) {\n continue;\n }\n\n // Check if it's an explicit FK relation: Alias!sourceField:targetTable(...)\n // Pattern: Word!word:word.word(...) or Word!word:word(...)\n const explicitFkMatch = trimmedToken.match(/^(\\w+)!(\\w+):([\\w.]+)\\((.+)\\)$/);\n if (explicitFkMatch) {\n const [, alias, sourceField, targetTable, innerSelect] = explicitFkMatch;\n\n // Recursively parse inner select\n const innerParsed = parseSelect(innerSelect);\n result.relations.push({\n name: targetTable,\n // Use target table as the relation name\n alias,\n columns: innerParsed.columns,\n relations: innerParsed.relations,\n explicitFk: {\n sourceField,\n targetTable\n // targetColumn defaults to \"id\" - handled at resolution time\n }\n });\n continue;\n }\n\n // Check if it's a standard relation: Name(...) or alias:Name(...)\n // Regex: optional alias followed by table name and parentheses with content\n const relationMatch = trimmedToken.match(/^(?:(\\w+):)?(\\w+)\\((.+)\\)$/);\n if (relationMatch) {\n const alias = relationMatch[1];\n const name = relationMatch[2];\n const innerSelect = relationMatch[3];\n\n // Recursively parse inner select\n const innerParsed = parseSelect(innerSelect);\n result.relations.push({\n name,\n alias,\n columns: innerParsed.columns,\n relations: innerParsed.relations\n });\n } else if (trimmedToken === \"*\") {\n // Wildcard - all columns\n result.columns = \"*\";\n } else {\n // It's a column, possibly with alias\n const column = parseColumnToken(trimmedToken);\n\n // Only add to columns array if we haven't set \"*\" already\n if (result.columns !== \"*\") {\n (result.columns as SelectColumn[]).push(column);\n }\n }\n }\n\n // If no explicit columns were added but we have relations, default to \"*\"\n if (Array.isArray(result.columns) && result.columns.length === 0) {\n result.columns = \"*\";\n }\n return result;\n}\n\n/**\n * Convert a parsed select back to a string representation (for debugging)\n */\nexport function stringifySelect(parsed: ParsedSelect): string {\n const parts: string[] = [];\n\n // Add columns\n if (parsed.columns === \"*\") {\n parts.push(\"*\");\n } else {\n for (const col of parsed.columns) {\n if (col.alias) {\n parts.push(`${col.alias}:${col.name}`);\n } else {\n parts.push(col.name);\n }\n }\n }\n\n // Add relations\n for (const rel of parsed.relations) {\n const innerStr = stringifySelect({\n columns: rel.columns,\n relations: rel.relations\n });\n if (rel.explicitFk) {\n // Explicit FK syntax: Alias!sourceField:targetTable(...)\n parts.push(`${rel.alias}!${rel.explicitFk.sourceField}:${rel.explicitFk.targetTable}(${innerStr})`);\n } else if (rel.alias) {\n parts.push(`${rel.alias}:${rel.name}(${innerStr})`);\n } else {\n parts.push(`${rel.name}(${innerStr})`);\n }\n }\n return parts.join(\", \");\n}\n\n/**\n * Extract all column names from a parsed select (for building SQL queries)\n * Does not include relation names.\n */\nexport function extractColumnNames(parsed: ParsedSelect): string[] | \"*\" {\n if (parsed.columns === \"*\") {\n return \"*\";\n }\n return parsed.columns.map(col => col.name);\n}\n\n/**\n * Extract all relation names from a parsed select\n */\nexport function extractRelationNames(parsed: ParsedSelect): string[] {\n return parsed.relations.map(rel => rel.alias ?? rel.name);\n}\n\n/**\n * Check if a select string references a specific relation\n */\nexport function hasRelation(parsed: ParsedSelect, relationName: string): boolean {\n return parsed.relations.some(rel => rel.name === relationName || rel.alias === relationName);\n}\n\n/**\n * Get the select configuration for a specific relation\n */\nexport function getRelationSelect(parsed: ParsedSelect, relationName: string): SelectRelation | undefined {\n return parsed.relations.find(rel => rel.name === relationName || rel.alias === relationName);\n}\n\n/**\n * Check if a parsed select contains any explicit FK relations.\n * This is used to determine if QueryExecutor should be used instead of PostgREST.\n *\n * @param parsed - The parsed select statement\n * @returns true if any relation uses explicit FK syntax\n */\nexport function hasExplicitFk(parsed: ParsedSelect): boolean {\n for (const relation of parsed.relations) {\n if (relation.explicitFk) {\n return true;\n }\n // Check nested relations recursively\n if (relation.relations.length > 0 && hasExplicitFk({\n columns: relation.columns,\n relations: relation.relations\n })) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a select string contains explicit FK syntax.\n * Quick check without full parsing for performance.\n *\n * @param select - The select string\n * @returns true if the string contains explicit FK syntax (! followed by field:table)\n */\nexport function selectHasExplicitFkSyntax(select: string): boolean {\n // Quick regex check for the explicit FK pattern: word!word:word\n return /\\w+!\\w+:[\\w.]+\\(/.test(select);\n}\n\n/**\n * Information about an explicit FK relation extracted from a select string.\n * Used for setting up realtime subscriptions on related tables.\n */\nexport interface ExtractedExplicitFk {\n /** The alias used for this relation in the select string (e.g., \"Sender\") */\n alias: string;\n /** The FK column on the parent table (e.g., \"senderId\") */\n sourceField: string;\n /** The target table, optionally schema-qualified (e.g., \"core.Profile\") */\n targetTable: string;\n /** Column to match in target table, defaults to \"id\" */\n targetColumn: string;\n}\n\n/**\n * Extract all explicit FK relations from a parsed select statement.\n * Recursively traverses the relation tree to find all explicit FK specs.\n *\n * @param parsed - The parsed select statement\n * @returns Array of extracted explicit FK relations\n *\n * @example\n * const parsed = parseSelect(\"*, Sender!senderId:core.Profile(*), Recipient!recipientId:core.Profile(*)\");\n * const explicitFks = extractExplicitFkRelations(parsed);\n * // Returns:\n * // [\n * // { alias: \"Sender\", sourceField: \"senderId\", targetTable: \"core.Profile\", targetColumn: \"id\" },\n * // { alias: \"Recipient\", sourceField: \"recipientId\", targetTable: \"core.Profile\", targetColumn: \"id\" }\n * // ]\n */\nexport function extractExplicitFkRelations(parsed: ParsedSelect): ExtractedExplicitFk[] {\n const results: ExtractedExplicitFk[] = [];\n function collectFromRelations(relations: SelectRelation[]): void {\n for (const relation of relations) {\n if (relation.explicitFk) {\n results.push({\n alias: relation.alias ?? relation.name,\n sourceField: relation.explicitFk.sourceField,\n targetTable: relation.explicitFk.targetTable,\n targetColumn: relation.explicitFk.targetColumn ?? \"id\"\n });\n }\n // Recursively check nested relations\n if (relation.relations.length > 0) {\n collectFromRelations(relation.relations);\n }\n }\n }\n collectFromRelations(parsed.relations);\n return results;\n}\n\n/**\n * Extract all unique target table names from explicit FK relations in a select string.\n * This is useful for setting up realtime watchers on related tables.\n *\n * @param select - The select string (e.g., \"*, Sender!senderId:core.Profile(*)\")\n * @returns Array of unique target table names\n *\n * @example\n * extractExplicitFkTables(\"*, Sender!senderId:core.Profile(*), Recipient!recipientId:core.Profile(*)\")\n * // Returns: [\"core.Profile\"]\n *\n * extractExplicitFkTables(\"*, Author!authorId:User(*), Editor!editorId:Admin(*)\")\n * // Returns: [\"User\", \"Admin\"]\n */\nexport function extractExplicitFkTables(select: string): string[] {\n // Quick check - if no explicit FK syntax, return empty array\n if (!selectHasExplicitFkSyntax(select)) {\n return [];\n }\n const parsed = parseSelect(select);\n const explicitFks = extractExplicitFkRelations(parsed);\n\n // Extract unique table names\n const uniqueTables = new Set<string>();\n for (const fk of explicitFks) {\n uniqueTables.add(fk.targetTable);\n }\n return Array.from(uniqueTables);\n}\n\n// Export the helper function for testing\nexport { tokenizeTopLevel };"],"mappings":"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","names":["trimmed"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useDeleteManyMutation,
|
|
3
3
|
useUpsertItem
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YUX6RGLZ.js";
|
|
5
5
|
import {
|
|
6
6
|
useSupabase
|
|
7
7
|
} from "./chunk-DMVUEJG2.js";
|
|
@@ -183,4 +183,4 @@ export {
|
|
|
183
183
|
useBatchDelete,
|
|
184
184
|
useBatchUpsert
|
|
185
185
|
};
|
|
186
|
-
//# sourceMappingURL=chunk-
|
|
186
|
+
//# sourceMappingURL=chunk-WM25QE7E.js.map
|