spacetimedb 2.0.3 → 2.1.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/LICENSE.txt +2 -2
- package/dist/angular/index.cjs +5 -1
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.mjs +5 -1
- package/dist/angular/index.mjs.map +1 -1
- package/dist/browser/angular/index.mjs +5 -1
- package/dist/browser/angular/index.mjs.map +1 -1
- package/dist/browser/react/index.mjs +8 -1
- package/dist/browser/react/index.mjs.map +1 -1
- package/dist/browser/svelte/index.mjs +5 -1
- package/dist/browser/svelte/index.mjs.map +1 -1
- package/dist/browser/vue/index.mjs +5 -1
- package/dist/browser/vue/index.mjs.map +1 -1
- package/dist/index.browser.mjs +148 -100
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.cjs +148 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +148 -100
- package/dist/index.mjs.map +1 -1
- package/dist/lib/algebraic_type.d.ts.map +1 -1
- package/dist/lib/binary_writer.d.ts +1 -0
- package/dist/lib/binary_writer.d.ts.map +1 -1
- package/dist/lib/indexes.d.ts +1 -1
- package/dist/lib/indexes.d.ts.map +1 -1
- package/dist/lib/query.d.ts +14 -7
- package/dist/lib/query.d.ts.map +1 -1
- package/dist/lib/schema.d.ts +2 -0
- package/dist/lib/schema.d.ts.map +1 -1
- package/dist/lib/table.d.ts +25 -2
- package/dist/lib/table.d.ts.map +1 -1
- package/dist/min/index.browser.mjs +1 -1
- package/dist/min/index.browser.mjs.map +1 -1
- package/dist/min/react/index.mjs +1 -1
- package/dist/min/react/index.mjs.map +1 -1
- package/dist/min/sdk/index.browser.mjs +1 -1
- package/dist/min/sdk/index.browser.mjs.map +1 -1
- package/dist/react/index.cjs +8 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.mjs +8 -1
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/useTable.d.ts.map +1 -1
- package/dist/sdk/db_connection_impl.d.ts.map +1 -1
- package/dist/sdk/index.browser.mjs +144 -98
- package/dist/sdk/index.browser.mjs.map +1 -1
- package/dist/sdk/index.cjs +144 -98
- package/dist/sdk/index.cjs.map +1 -1
- package/dist/sdk/index.mjs +144 -98
- package/dist/sdk/index.mjs.map +1 -1
- package/dist/sdk/table_cache.d.ts.map +1 -1
- package/dist/sdk/websocket_decompress_adapter.d.ts +17 -7
- package/dist/sdk/websocket_decompress_adapter.d.ts.map +1 -1
- package/dist/sdk/websocket_test_adapter.d.ts +3 -2
- package/dist/sdk/websocket_test_adapter.d.ts.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.mjs +88 -30
- package/dist/server/index.mjs.map +1 -1
- package/dist/svelte/index.cjs +5 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.mjs +5 -1
- package/dist/svelte/index.mjs.map +1 -1
- package/dist/tanstack/SpacetimeDBQueryClient.d.ts +1 -0
- package/dist/tanstack/SpacetimeDBQueryClient.d.ts.map +1 -1
- package/dist/tanstack/index.cjs +26 -1
- package/dist/tanstack/index.cjs.map +1 -1
- package/dist/tanstack/index.mjs +26 -1
- package/dist/tanstack/index.mjs.map +1 -1
- package/dist/vue/index.cjs +5 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.mjs +5 -1
- package/dist/vue/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/lib/algebraic_type.ts +5 -1
- package/src/lib/binary_writer.ts +4 -0
- package/src/lib/indexes.ts +1 -1
- package/src/lib/query.ts +90 -25
- package/src/lib/schema.ts +66 -24
- package/src/lib/table.ts +47 -10
- package/src/react/useTable.ts +5 -0
- package/src/sdk/db_connection_impl.ts +38 -43
- package/src/sdk/table_cache.ts +14 -11
- package/src/sdk/websocket_decompress_adapter.ts +42 -45
- package/src/sdk/websocket_test_adapter.ts +3 -2
- package/src/server/index.ts +1 -0
- package/src/server/runtime.ts +7 -3
- package/src/server/schema.test-d.ts +37 -0
- package/src/server/view.test-d.ts +6 -0
- package/src/tanstack/SpacetimeDBQueryClient.ts +24 -0
package/dist/index.mjs
CHANGED
|
@@ -581,6 +581,9 @@ var BinaryWriter = class {
|
|
|
581
581
|
constructor(init) {
|
|
582
582
|
this.buffer = typeof init === "number" ? new ResizableBuffer(init) : init;
|
|
583
583
|
}
|
|
584
|
+
clear() {
|
|
585
|
+
this.offset = 0;
|
|
586
|
+
}
|
|
584
587
|
reset(buffer) {
|
|
585
588
|
this.buffer = buffer;
|
|
586
589
|
this.offset = 0;
|
|
@@ -1220,7 +1223,8 @@ writer.offset += ${primitiveSizes[tag]};` : `writer.write${tag}(value.${name});`
|
|
|
1220
1223
|
const result = { ${ty.elements.map(getElementInitializer).join(", ")} };
|
|
1221
1224
|
const view = reader.view;
|
|
1222
1225
|
${ty.elements.map(
|
|
1223
|
-
({ name, algebraicType: { tag } }) => tag in primitiveJSName ? `result.${name} = view.
|
|
1226
|
+
({ name, algebraicType: { tag } }) => tag in primitiveJSName ? tag === "Bool" ? `result.${name} = view.getUint8(reader.offset) !== 0;
|
|
1227
|
+
reader.offset += 1;` : `result.${name} = view.get${primitiveJSName[tag]}(reader.offset, ${primitiveSizes[tag] > 1 ? "true" : ""});
|
|
1224
1228
|
reader.offset += ${primitiveSizes[tag]};` : `result.${name} = reader.read${tag}();`
|
|
1225
1229
|
).join("\n")}
|
|
1226
1230
|
return result;`;
|
|
@@ -1628,7 +1632,7 @@ var FromBuilder = class _FromBuilder {
|
|
|
1628
1632
|
}
|
|
1629
1633
|
[QueryBrand] = true;
|
|
1630
1634
|
where(predicate) {
|
|
1631
|
-
const newCondition = predicate(this.table.cols);
|
|
1635
|
+
const newCondition = normalizePredicateExpr(predicate(this.table.cols));
|
|
1632
1636
|
const nextWhere = this.whereClause ? this.whereClause.and(newCondition) : newCondition;
|
|
1633
1637
|
return new _FromBuilder(this.table, nextWhere);
|
|
1634
1638
|
}
|
|
@@ -1723,7 +1727,8 @@ function createRowExpr(tableDef) {
|
|
|
1723
1727
|
const column = new ColumnExpression(
|
|
1724
1728
|
tableDef.sourceName,
|
|
1725
1729
|
columnName,
|
|
1726
|
-
columnBuilder.typeBuilder.algebraicType
|
|
1730
|
+
columnBuilder.typeBuilder.algebraicType,
|
|
1731
|
+
columnBuilder.columnMetadata.name
|
|
1727
1732
|
);
|
|
1728
1733
|
row[columnName] = Object.freeze(column);
|
|
1729
1734
|
}
|
|
@@ -1741,14 +1746,18 @@ function renderSelectSqlWithJoins(table2, where, extraClauses = []) {
|
|
|
1741
1746
|
}
|
|
1742
1747
|
var ColumnExpression = class {
|
|
1743
1748
|
type = "column";
|
|
1749
|
+
// This is the column accessor
|
|
1744
1750
|
column;
|
|
1751
|
+
// The name of the column in the database.
|
|
1752
|
+
columnName;
|
|
1745
1753
|
table;
|
|
1746
1754
|
// phantom: actual runtime value is undefined
|
|
1747
1755
|
tsValueType;
|
|
1748
1756
|
spacetimeType;
|
|
1749
|
-
constructor(table2, column, spacetimeType) {
|
|
1757
|
+
constructor(table2, column, spacetimeType, columnName) {
|
|
1750
1758
|
this.table = table2;
|
|
1751
1759
|
this.column = column;
|
|
1760
|
+
this.columnName = columnName || column;
|
|
1752
1761
|
this.spacetimeType = spacetimeType;
|
|
1753
1762
|
}
|
|
1754
1763
|
eq(x) {
|
|
@@ -1805,15 +1814,36 @@ function normalizeValue(val) {
|
|
|
1805
1814
|
}
|
|
1806
1815
|
return literal(val);
|
|
1807
1816
|
}
|
|
1817
|
+
function normalizePredicateExpr(value) {
|
|
1818
|
+
if (value instanceof BooleanExpr) return value;
|
|
1819
|
+
if (typeof value === "boolean") {
|
|
1820
|
+
return new BooleanExpr({
|
|
1821
|
+
type: "eq",
|
|
1822
|
+
left: literal(value),
|
|
1823
|
+
right: literal(true)
|
|
1824
|
+
});
|
|
1825
|
+
}
|
|
1826
|
+
return new BooleanExpr({
|
|
1827
|
+
type: "eq",
|
|
1828
|
+
left: value,
|
|
1829
|
+
right: literal(true)
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1808
1832
|
var BooleanExpr = class _BooleanExpr {
|
|
1809
1833
|
constructor(data) {
|
|
1810
1834
|
this.data = data;
|
|
1811
1835
|
}
|
|
1812
1836
|
and(other) {
|
|
1813
|
-
return new _BooleanExpr({
|
|
1837
|
+
return new _BooleanExpr({
|
|
1838
|
+
type: "and",
|
|
1839
|
+
clauses: [this.data, other.data]
|
|
1840
|
+
});
|
|
1814
1841
|
}
|
|
1815
1842
|
or(other) {
|
|
1816
|
-
return new _BooleanExpr({
|
|
1843
|
+
return new _BooleanExpr({
|
|
1844
|
+
type: "or",
|
|
1845
|
+
clauses: [this.data, other.data]
|
|
1846
|
+
});
|
|
1817
1847
|
}
|
|
1818
1848
|
not() {
|
|
1819
1849
|
return new _BooleanExpr({ type: "not", clause: this.data });
|
|
@@ -1822,13 +1852,15 @@ var BooleanExpr = class _BooleanExpr {
|
|
|
1822
1852
|
function not(clause) {
|
|
1823
1853
|
return new BooleanExpr({ type: "not", clause: clause.data });
|
|
1824
1854
|
}
|
|
1825
|
-
function and(...
|
|
1855
|
+
function and(first, second, ...rest) {
|
|
1856
|
+
const clauses = [first, second, ...rest];
|
|
1826
1857
|
return new BooleanExpr({
|
|
1827
1858
|
type: "and",
|
|
1828
1859
|
clauses: clauses.map((c) => c.data)
|
|
1829
1860
|
});
|
|
1830
1861
|
}
|
|
1831
|
-
function or(...
|
|
1862
|
+
function or(first, second, ...rest) {
|
|
1863
|
+
const clauses = [first, second, ...rest];
|
|
1832
1864
|
return new BooleanExpr({
|
|
1833
1865
|
type: "or",
|
|
1834
1866
|
clauses: clauses.map((c) => c.data)
|
|
@@ -1865,7 +1897,7 @@ function valueExprToSql(expr, tableAlias) {
|
|
|
1865
1897
|
return literalValueToSql(expr.value);
|
|
1866
1898
|
}
|
|
1867
1899
|
const table2 = expr.table;
|
|
1868
|
-
return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.
|
|
1900
|
+
return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.columnName)}`;
|
|
1869
1901
|
}
|
|
1870
1902
|
function literalValueToSql(value) {
|
|
1871
1903
|
if (value === null || value === void 0) {
|
|
@@ -4446,9 +4478,7 @@ var TableCacheImpl = class {
|
|
|
4446
4478
|
this.tableDef = tableDef;
|
|
4447
4479
|
this.rows = /* @__PURE__ */ new Map();
|
|
4448
4480
|
this.emitter = new EventEmitter();
|
|
4449
|
-
const
|
|
4450
|
-
for (const idx of indexesDef) {
|
|
4451
|
-
const idxDef = idx;
|
|
4481
|
+
for (const idxDef of this.tableDef.resolvedIndexes) {
|
|
4452
4482
|
const index = this.#makeReadonlyIndex(this.tableDef, idxDef);
|
|
4453
4483
|
this[idxDef.name] = index;
|
|
4454
4484
|
}
|
|
@@ -5005,37 +5035,39 @@ async function resolveWS() {
|
|
|
5005
5035
|
|
|
5006
5036
|
// src/sdk/websocket_decompress_adapter.ts
|
|
5007
5037
|
var WebsocketDecompressAdapter = class _WebsocketDecompressAdapter {
|
|
5008
|
-
onclose
|
|
5009
|
-
|
|
5010
|
-
onmessage;
|
|
5011
|
-
onerror;
|
|
5012
|
-
#ws;
|
|
5013
|
-
async #handleOnMessage(msg) {
|
|
5014
|
-
const buffer = new Uint8Array(msg.data);
|
|
5015
|
-
let decompressed;
|
|
5016
|
-
if (buffer[0] === 0) {
|
|
5017
|
-
decompressed = buffer.slice(1);
|
|
5018
|
-
} else if (buffer[0] === 1) {
|
|
5019
|
-
throw new Error(
|
|
5020
|
-
"Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection."
|
|
5021
|
-
);
|
|
5022
|
-
} else if (buffer[0] === 2) {
|
|
5023
|
-
decompressed = await decompress(buffer.slice(1), "gzip");
|
|
5024
|
-
} else {
|
|
5025
|
-
throw new Error(
|
|
5026
|
-
"Unexpected Compression Algorithm. Please use `gzip` or `none`"
|
|
5027
|
-
);
|
|
5028
|
-
}
|
|
5029
|
-
this.onmessage?.({ data: decompressed });
|
|
5038
|
+
set onclose(handler) {
|
|
5039
|
+
this.#ws.onclose = handler;
|
|
5030
5040
|
}
|
|
5031
|
-
|
|
5032
|
-
this.onopen
|
|
5041
|
+
set onopen(handler) {
|
|
5042
|
+
this.#ws.onopen = handler;
|
|
5033
5043
|
}
|
|
5034
|
-
|
|
5035
|
-
this.
|
|
5044
|
+
set onmessage(handler) {
|
|
5045
|
+
this.#ws.onmessage = async (msg) => {
|
|
5046
|
+
const data = await this.#decompress(new Uint8Array(msg.data));
|
|
5047
|
+
handler({ data });
|
|
5048
|
+
};
|
|
5036
5049
|
}
|
|
5037
|
-
|
|
5038
|
-
this.
|
|
5050
|
+
set onerror(handler) {
|
|
5051
|
+
this.#ws.onerror = handler;
|
|
5052
|
+
}
|
|
5053
|
+
#ws;
|
|
5054
|
+
async #decompress(buffer) {
|
|
5055
|
+
const tag = buffer[0];
|
|
5056
|
+
const data = buffer.subarray(1);
|
|
5057
|
+
switch (tag) {
|
|
5058
|
+
case 0:
|
|
5059
|
+
return data;
|
|
5060
|
+
case 1:
|
|
5061
|
+
throw new Error(
|
|
5062
|
+
"Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection."
|
|
5063
|
+
);
|
|
5064
|
+
case 2:
|
|
5065
|
+
return await decompress(data, "gzip");
|
|
5066
|
+
default:
|
|
5067
|
+
throw new Error(
|
|
5068
|
+
"Unexpected Compression Algorithm. Please use `gzip` or `none`"
|
|
5069
|
+
);
|
|
5070
|
+
}
|
|
5039
5071
|
}
|
|
5040
5072
|
send(msg) {
|
|
5041
5073
|
this.#ws.send(msg);
|
|
@@ -5044,14 +5076,6 @@ var WebsocketDecompressAdapter = class _WebsocketDecompressAdapter {
|
|
|
5044
5076
|
this.#ws.close();
|
|
5045
5077
|
}
|
|
5046
5078
|
constructor(ws) {
|
|
5047
|
-
this.onmessage = void 0;
|
|
5048
|
-
this.onopen = void 0;
|
|
5049
|
-
this.onmessage = void 0;
|
|
5050
|
-
this.onerror = void 0;
|
|
5051
|
-
ws.onmessage = this.#handleOnMessage.bind(this);
|
|
5052
|
-
ws.onerror = this.#handleOnError.bind(this);
|
|
5053
|
-
ws.onclose = this.#handleOnClose.bind(this);
|
|
5054
|
-
ws.onopen = this.#handleOnOpen.bind(this);
|
|
5055
5079
|
ws.binaryType = "arraybuffer";
|
|
5056
5080
|
this.#ws = ws;
|
|
5057
5081
|
}
|
|
@@ -5688,12 +5712,13 @@ var DbConnectionImpl = class {
|
|
|
5688
5712
|
}
|
|
5689
5713
|
#makeReducers(def) {
|
|
5690
5714
|
const out = {};
|
|
5715
|
+
const writer = new BinaryWriter(1024);
|
|
5691
5716
|
for (const reducer of def.reducers) {
|
|
5692
5717
|
const reducerName = reducer.name;
|
|
5693
5718
|
const key = reducer.accessorName;
|
|
5694
5719
|
const { serialize: serializeArgs } = this.#reducerArgsSerializers[reducerName];
|
|
5695
5720
|
out[key] = (params) => {
|
|
5696
|
-
|
|
5721
|
+
writer.clear();
|
|
5697
5722
|
serializeArgs(writer, params);
|
|
5698
5723
|
const argsBuffer = writer.getBuffer();
|
|
5699
5724
|
return this.callReducer(reducerName, argsBuffer, params);
|
|
@@ -5703,12 +5728,13 @@ var DbConnectionImpl = class {
|
|
|
5703
5728
|
}
|
|
5704
5729
|
#makeProcedures(def) {
|
|
5705
5730
|
const out = {};
|
|
5731
|
+
const writer = new BinaryWriter(1024);
|
|
5706
5732
|
for (const procedure of def.procedures) {
|
|
5707
5733
|
const procedureName = procedure.name;
|
|
5708
5734
|
const key = procedure.accessorName;
|
|
5709
5735
|
const { serializeArgs, deserializeReturn } = this.#procedureSerializers[procedureName];
|
|
5710
5736
|
out[key] = (params) => {
|
|
5711
|
-
|
|
5737
|
+
writer.clear();
|
|
5712
5738
|
serializeArgs(writer, params);
|
|
5713
5739
|
const argsBuffer = writer.getBuffer();
|
|
5714
5740
|
return this.callProcedure(procedureName, argsBuffer).then((returnBuf) => {
|
|
@@ -5863,34 +5889,32 @@ var DbConnectionImpl = class {
|
|
|
5863
5889
|
}
|
|
5864
5890
|
return this.#mergeTableUpdates(updates);
|
|
5865
5891
|
}
|
|
5866
|
-
#sendEncoded(wsResolved, message) {
|
|
5867
|
-
stdbLogger(
|
|
5868
|
-
"trace",
|
|
5869
|
-
() => `Sending message to server: ${stringify(message)}`
|
|
5870
|
-
);
|
|
5871
|
-
const writer = new BinaryWriter(1024);
|
|
5872
|
-
ClientMessage.serialize(writer, message);
|
|
5873
|
-
const encoded = writer.getBuffer();
|
|
5874
|
-
wsResolved.send(encoded);
|
|
5875
|
-
}
|
|
5876
5892
|
#flushOutboundQueue(wsResolved) {
|
|
5877
|
-
if (!this.isActive || this.#outboundQueue.length === 0) {
|
|
5878
|
-
return;
|
|
5879
|
-
}
|
|
5880
5893
|
const pending = this.#outboundQueue.splice(0);
|
|
5881
5894
|
for (const message of pending) {
|
|
5882
|
-
|
|
5895
|
+
wsResolved.send(message);
|
|
5883
5896
|
}
|
|
5884
5897
|
}
|
|
5898
|
+
#clientMessageEncoder = new BinaryWriter(1024);
|
|
5885
5899
|
#sendMessage(message) {
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
this.#flushOutboundQueue(
|
|
5892
|
-
|
|
5893
|
-
|
|
5900
|
+
const writer = this.#clientMessageEncoder;
|
|
5901
|
+
writer.clear();
|
|
5902
|
+
ClientMessage.serialize(writer, message);
|
|
5903
|
+
const encoded = writer.getBuffer();
|
|
5904
|
+
if (this.ws && this.isActive) {
|
|
5905
|
+
if (this.#outboundQueue.length) this.#flushOutboundQueue(this.ws);
|
|
5906
|
+
stdbLogger(
|
|
5907
|
+
"trace",
|
|
5908
|
+
() => `Sending message to server: ${stringify(message)}`
|
|
5909
|
+
);
|
|
5910
|
+
this.ws.send(encoded);
|
|
5911
|
+
} else {
|
|
5912
|
+
stdbLogger(
|
|
5913
|
+
"trace",
|
|
5914
|
+
() => `Queuing message to server: ${stringify(message)}`
|
|
5915
|
+
);
|
|
5916
|
+
this.#outboundQueue.push(encoded.slice());
|
|
5917
|
+
}
|
|
5894
5918
|
}
|
|
5895
5919
|
#nextEventId() {
|
|
5896
5920
|
this.#eventId += 1;
|
|
@@ -6232,11 +6256,7 @@ var DbConnectionImpl = class {
|
|
|
6232
6256
|
* ```
|
|
6233
6257
|
*/
|
|
6234
6258
|
disconnect() {
|
|
6235
|
-
this.wsPromise.then((
|
|
6236
|
-
if (wsResolved) {
|
|
6237
|
-
wsResolved.close();
|
|
6238
|
-
}
|
|
6239
|
-
});
|
|
6259
|
+
this.wsPromise.then((ws) => ws?.close());
|
|
6240
6260
|
}
|
|
6241
6261
|
on(eventName, callback) {
|
|
6242
6262
|
this.#emitter.on(eventName, callback);
|
|
@@ -6266,17 +6286,45 @@ var DbConnectionImpl = class {
|
|
|
6266
6286
|
|
|
6267
6287
|
// src/lib/schema.ts
|
|
6268
6288
|
function tablesToSchema(ctx, tables) {
|
|
6289
|
+
const tableDefs = /* @__PURE__ */ Object.create(null);
|
|
6290
|
+
for (const [accName, schema2] of Object.entries(tables)) {
|
|
6291
|
+
tableDefs[accName] = tableToSchema(
|
|
6292
|
+
accName,
|
|
6293
|
+
schema2,
|
|
6294
|
+
schema2.tableDef(ctx, accName)
|
|
6295
|
+
);
|
|
6296
|
+
}
|
|
6269
6297
|
return {
|
|
6270
|
-
tables:
|
|
6271
|
-
Object.entries(tables).map(([accName, schema2]) => [
|
|
6272
|
-
accName,
|
|
6273
|
-
tableToSchema(accName, schema2, schema2.tableDef(ctx, accName))
|
|
6274
|
-
])
|
|
6275
|
-
)
|
|
6298
|
+
tables: tableDefs
|
|
6276
6299
|
};
|
|
6277
6300
|
}
|
|
6278
6301
|
function tableToSchema(accName, schema2, tableDef) {
|
|
6279
6302
|
const getColName = (i) => schema2.rowType.algebraicType.value.elements[i].name;
|
|
6303
|
+
const resolvedIndexes = tableDef.indexes.map(
|
|
6304
|
+
(idx) => {
|
|
6305
|
+
const accessorName = idx.accessorName;
|
|
6306
|
+
if (typeof accessorName !== "string" || accessorName.length === 0) {
|
|
6307
|
+
throw new TypeError(
|
|
6308
|
+
`Index '${idx.sourceName ?? "<unknown>"}' on table '${tableDef.sourceName}' is missing accessor name`
|
|
6309
|
+
);
|
|
6310
|
+
}
|
|
6311
|
+
const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value;
|
|
6312
|
+
const unique = tableDef.constraints.some(
|
|
6313
|
+
(c) => c.data.tag === "Unique" && c.data.value.columns.every((col) => columnIds.includes(col))
|
|
6314
|
+
);
|
|
6315
|
+
const algorithm = {
|
|
6316
|
+
BTree: "btree",
|
|
6317
|
+
Hash: "hash",
|
|
6318
|
+
Direct: "direct"
|
|
6319
|
+
}[idx.algorithm.tag];
|
|
6320
|
+
return {
|
|
6321
|
+
name: accessorName,
|
|
6322
|
+
unique,
|
|
6323
|
+
algorithm,
|
|
6324
|
+
columns: columnIds.map(getColName)
|
|
6325
|
+
};
|
|
6326
|
+
}
|
|
6327
|
+
);
|
|
6280
6328
|
return {
|
|
6281
6329
|
// For client,`schama.tableName` will always be there as canonical name.
|
|
6282
6330
|
// For module, if explicit name is not provided via `name`, accessor name will
|
|
@@ -6286,26 +6334,16 @@ function tableToSchema(accName, schema2, tableDef) {
|
|
|
6286
6334
|
columns: schema2.rowType.row,
|
|
6287
6335
|
// typed as T[i]['rowType']['row'] under TablesToSchema<T>
|
|
6288
6336
|
rowType: schema2.rowSpacetimeType,
|
|
6337
|
+
// Keep declarative indexes in their original shape for type-level consumers.
|
|
6338
|
+
indexes: schema2.idxs,
|
|
6289
6339
|
constraints: tableDef.constraints.map((c) => ({
|
|
6290
6340
|
name: c.sourceName,
|
|
6291
6341
|
constraint: "unique",
|
|
6292
6342
|
columns: c.data.value.columns.map(getColName)
|
|
6293
6343
|
})),
|
|
6294
|
-
//
|
|
6295
|
-
//
|
|
6296
|
-
|
|
6297
|
-
// We should stop lying about our types.
|
|
6298
|
-
indexes: tableDef.indexes.map((idx) => {
|
|
6299
|
-
const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value;
|
|
6300
|
-
return {
|
|
6301
|
-
name: idx.accessorName,
|
|
6302
|
-
unique: tableDef.constraints.some(
|
|
6303
|
-
(c) => c.data.value.columns.every((col) => columnIds.includes(col))
|
|
6304
|
-
),
|
|
6305
|
-
algorithm: idx.algorithm.tag.toLowerCase(),
|
|
6306
|
-
columns: columnIds.map(getColName)
|
|
6307
|
-
};
|
|
6308
|
-
}),
|
|
6344
|
+
// Expose resolved runtime indexes separately so runtime users don't have to
|
|
6345
|
+
// reinterpret `indexes` with unsafe casts.
|
|
6346
|
+
resolvedIndexes,
|
|
6309
6347
|
tableDef,
|
|
6310
6348
|
...tableDef.isEvent ? { isEvent: true } : {}
|
|
6311
6349
|
};
|
|
@@ -7129,6 +7167,14 @@ function table(opts, row, ..._) {
|
|
|
7129
7167
|
}
|
|
7130
7168
|
}
|
|
7131
7169
|
for (const indexOpts of userIndexes ?? []) {
|
|
7170
|
+
const accessor = indexOpts.accessor;
|
|
7171
|
+
if (typeof accessor !== "string" || accessor.length === 0) {
|
|
7172
|
+
const tableLabel = name ?? "<unnamed>";
|
|
7173
|
+
const indexLabel = indexOpts.name ?? "<unnamed>";
|
|
7174
|
+
throw new TypeError(
|
|
7175
|
+
`Index '${indexLabel}' on table '${tableLabel}' must define a non-empty 'accessor'`
|
|
7176
|
+
);
|
|
7177
|
+
}
|
|
7132
7178
|
let algorithm;
|
|
7133
7179
|
switch (indexOpts.algorithm) {
|
|
7134
7180
|
case "btree":
|
|
@@ -7149,7 +7195,7 @@ function table(opts, row, ..._) {
|
|
|
7149
7195
|
}
|
|
7150
7196
|
indexes.push({
|
|
7151
7197
|
sourceName: void 0,
|
|
7152
|
-
accessorName:
|
|
7198
|
+
accessorName: accessor,
|
|
7153
7199
|
algorithm,
|
|
7154
7200
|
canonicalName: indexOpts.name
|
|
7155
7201
|
});
|
|
@@ -7199,7 +7245,9 @@ function table(opts, row, ..._) {
|
|
|
7199
7245
|
isEvent
|
|
7200
7246
|
};
|
|
7201
7247
|
},
|
|
7202
|
-
|
|
7248
|
+
// Preserve the declared index options as runtime data so `tableToSchema`
|
|
7249
|
+
// can expose them without type-smuggling.
|
|
7250
|
+
idxs: userIndexes,
|
|
7203
7251
|
constraints,
|
|
7204
7252
|
schedule
|
|
7205
7253
|
};
|