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/sdk/index.cjs
CHANGED
|
@@ -583,6 +583,9 @@ var BinaryWriter = class {
|
|
|
583
583
|
constructor(init) {
|
|
584
584
|
this.buffer = typeof init === "number" ? new ResizableBuffer(init) : init;
|
|
585
585
|
}
|
|
586
|
+
clear() {
|
|
587
|
+
this.offset = 0;
|
|
588
|
+
}
|
|
586
589
|
reset(buffer) {
|
|
587
590
|
this.buffer = buffer;
|
|
588
591
|
this.offset = 0;
|
|
@@ -1176,7 +1179,8 @@ writer.offset += ${primitiveSizes[tag]};` : `writer.write${tag}(value.${name});`
|
|
|
1176
1179
|
const result = { ${ty.elements.map(getElementInitializer).join(", ")} };
|
|
1177
1180
|
const view = reader.view;
|
|
1178
1181
|
${ty.elements.map(
|
|
1179
|
-
({ name, algebraicType: { tag } }) => tag in primitiveJSName ? `result.${name} = view.
|
|
1182
|
+
({ name, algebraicType: { tag } }) => tag in primitiveJSName ? tag === "Bool" ? `result.${name} = view.getUint8(reader.offset) !== 0;
|
|
1183
|
+
reader.offset += 1;` : `result.${name} = view.get${primitiveJSName[tag]}(reader.offset, ${primitiveSizes[tag] > 1 ? "true" : ""});
|
|
1180
1184
|
reader.offset += ${primitiveSizes[tag]};` : `result.${name} = reader.read${tag}();`
|
|
1181
1185
|
).join("\n")}
|
|
1182
1186
|
return result;`;
|
|
@@ -1577,7 +1581,7 @@ var FromBuilder = class _FromBuilder {
|
|
|
1577
1581
|
}
|
|
1578
1582
|
[QueryBrand] = true;
|
|
1579
1583
|
where(predicate) {
|
|
1580
|
-
const newCondition = predicate(this.table.cols);
|
|
1584
|
+
const newCondition = normalizePredicateExpr(predicate(this.table.cols));
|
|
1581
1585
|
const nextWhere = this.whereClause ? this.whereClause.and(newCondition) : newCondition;
|
|
1582
1586
|
return new _FromBuilder(this.table, nextWhere);
|
|
1583
1587
|
}
|
|
@@ -1672,7 +1676,8 @@ function createRowExpr(tableDef) {
|
|
|
1672
1676
|
const column = new ColumnExpression(
|
|
1673
1677
|
tableDef.sourceName,
|
|
1674
1678
|
columnName,
|
|
1675
|
-
columnBuilder.typeBuilder.algebraicType
|
|
1679
|
+
columnBuilder.typeBuilder.algebraicType,
|
|
1680
|
+
columnBuilder.columnMetadata.name
|
|
1676
1681
|
);
|
|
1677
1682
|
row[columnName] = Object.freeze(column);
|
|
1678
1683
|
}
|
|
@@ -1690,14 +1695,18 @@ function renderSelectSqlWithJoins(table2, where, extraClauses = []) {
|
|
|
1690
1695
|
}
|
|
1691
1696
|
var ColumnExpression = class {
|
|
1692
1697
|
type = "column";
|
|
1698
|
+
// This is the column accessor
|
|
1693
1699
|
column;
|
|
1700
|
+
// The name of the column in the database.
|
|
1701
|
+
columnName;
|
|
1694
1702
|
table;
|
|
1695
1703
|
// phantom: actual runtime value is undefined
|
|
1696
1704
|
tsValueType;
|
|
1697
1705
|
spacetimeType;
|
|
1698
|
-
constructor(table2, column, spacetimeType) {
|
|
1706
|
+
constructor(table2, column, spacetimeType, columnName) {
|
|
1699
1707
|
this.table = table2;
|
|
1700
1708
|
this.column = column;
|
|
1709
|
+
this.columnName = columnName || column;
|
|
1701
1710
|
this.spacetimeType = spacetimeType;
|
|
1702
1711
|
}
|
|
1703
1712
|
eq(x) {
|
|
@@ -1754,15 +1763,36 @@ function normalizeValue(val) {
|
|
|
1754
1763
|
}
|
|
1755
1764
|
return literal(val);
|
|
1756
1765
|
}
|
|
1766
|
+
function normalizePredicateExpr(value) {
|
|
1767
|
+
if (value instanceof BooleanExpr) return value;
|
|
1768
|
+
if (typeof value === "boolean") {
|
|
1769
|
+
return new BooleanExpr({
|
|
1770
|
+
type: "eq",
|
|
1771
|
+
left: literal(value),
|
|
1772
|
+
right: literal(true)
|
|
1773
|
+
});
|
|
1774
|
+
}
|
|
1775
|
+
return new BooleanExpr({
|
|
1776
|
+
type: "eq",
|
|
1777
|
+
left: value,
|
|
1778
|
+
right: literal(true)
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1757
1781
|
var BooleanExpr = class _BooleanExpr {
|
|
1758
1782
|
constructor(data) {
|
|
1759
1783
|
this.data = data;
|
|
1760
1784
|
}
|
|
1761
1785
|
and(other) {
|
|
1762
|
-
return new _BooleanExpr({
|
|
1786
|
+
return new _BooleanExpr({
|
|
1787
|
+
type: "and",
|
|
1788
|
+
clauses: [this.data, other.data]
|
|
1789
|
+
});
|
|
1763
1790
|
}
|
|
1764
1791
|
or(other) {
|
|
1765
|
-
return new _BooleanExpr({
|
|
1792
|
+
return new _BooleanExpr({
|
|
1793
|
+
type: "or",
|
|
1794
|
+
clauses: [this.data, other.data]
|
|
1795
|
+
});
|
|
1766
1796
|
}
|
|
1767
1797
|
not() {
|
|
1768
1798
|
return new _BooleanExpr({ type: "not", clause: this.data });
|
|
@@ -1799,7 +1829,7 @@ function valueExprToSql(expr, tableAlias) {
|
|
|
1799
1829
|
return literalValueToSql(expr.value);
|
|
1800
1830
|
}
|
|
1801
1831
|
const table2 = expr.table;
|
|
1802
|
-
return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.
|
|
1832
|
+
return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.columnName)}`;
|
|
1803
1833
|
}
|
|
1804
1834
|
function literalValueToSql(value) {
|
|
1805
1835
|
if (value === null || value === void 0) {
|
|
@@ -4315,9 +4345,7 @@ var TableCacheImpl = class {
|
|
|
4315
4345
|
this.tableDef = tableDef;
|
|
4316
4346
|
this.rows = /* @__PURE__ */ new Map();
|
|
4317
4347
|
this.emitter = new EventEmitter();
|
|
4318
|
-
const
|
|
4319
|
-
for (const idx of indexesDef) {
|
|
4320
|
-
const idxDef = idx;
|
|
4348
|
+
for (const idxDef of this.tableDef.resolvedIndexes) {
|
|
4321
4349
|
const index = this.#makeReadonlyIndex(this.tableDef, idxDef);
|
|
4322
4350
|
this[idxDef.name] = index;
|
|
4323
4351
|
}
|
|
@@ -4874,37 +4902,39 @@ async function resolveWS() {
|
|
|
4874
4902
|
|
|
4875
4903
|
// src/sdk/websocket_decompress_adapter.ts
|
|
4876
4904
|
var WebsocketDecompressAdapter = class _WebsocketDecompressAdapter {
|
|
4877
|
-
onclose
|
|
4878
|
-
|
|
4879
|
-
onmessage;
|
|
4880
|
-
onerror;
|
|
4881
|
-
#ws;
|
|
4882
|
-
async #handleOnMessage(msg) {
|
|
4883
|
-
const buffer = new Uint8Array(msg.data);
|
|
4884
|
-
let decompressed;
|
|
4885
|
-
if (buffer[0] === 0) {
|
|
4886
|
-
decompressed = buffer.slice(1);
|
|
4887
|
-
} else if (buffer[0] === 1) {
|
|
4888
|
-
throw new Error(
|
|
4889
|
-
"Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection."
|
|
4890
|
-
);
|
|
4891
|
-
} else if (buffer[0] === 2) {
|
|
4892
|
-
decompressed = await decompress(buffer.slice(1), "gzip");
|
|
4893
|
-
} else {
|
|
4894
|
-
throw new Error(
|
|
4895
|
-
"Unexpected Compression Algorithm. Please use `gzip` or `none`"
|
|
4896
|
-
);
|
|
4897
|
-
}
|
|
4898
|
-
this.onmessage?.({ data: decompressed });
|
|
4905
|
+
set onclose(handler) {
|
|
4906
|
+
this.#ws.onclose = handler;
|
|
4899
4907
|
}
|
|
4900
|
-
|
|
4901
|
-
this.onopen
|
|
4908
|
+
set onopen(handler) {
|
|
4909
|
+
this.#ws.onopen = handler;
|
|
4902
4910
|
}
|
|
4903
|
-
|
|
4904
|
-
this.
|
|
4911
|
+
set onmessage(handler) {
|
|
4912
|
+
this.#ws.onmessage = async (msg) => {
|
|
4913
|
+
const data = await this.#decompress(new Uint8Array(msg.data));
|
|
4914
|
+
handler({ data });
|
|
4915
|
+
};
|
|
4905
4916
|
}
|
|
4906
|
-
|
|
4907
|
-
this.
|
|
4917
|
+
set onerror(handler) {
|
|
4918
|
+
this.#ws.onerror = handler;
|
|
4919
|
+
}
|
|
4920
|
+
#ws;
|
|
4921
|
+
async #decompress(buffer) {
|
|
4922
|
+
const tag = buffer[0];
|
|
4923
|
+
const data = buffer.subarray(1);
|
|
4924
|
+
switch (tag) {
|
|
4925
|
+
case 0:
|
|
4926
|
+
return data;
|
|
4927
|
+
case 1:
|
|
4928
|
+
throw new Error(
|
|
4929
|
+
"Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection."
|
|
4930
|
+
);
|
|
4931
|
+
case 2:
|
|
4932
|
+
return await decompress(data, "gzip");
|
|
4933
|
+
default:
|
|
4934
|
+
throw new Error(
|
|
4935
|
+
"Unexpected Compression Algorithm. Please use `gzip` or `none`"
|
|
4936
|
+
);
|
|
4937
|
+
}
|
|
4908
4938
|
}
|
|
4909
4939
|
send(msg) {
|
|
4910
4940
|
this.#ws.send(msg);
|
|
@@ -4913,14 +4943,6 @@ var WebsocketDecompressAdapter = class _WebsocketDecompressAdapter {
|
|
|
4913
4943
|
this.#ws.close();
|
|
4914
4944
|
}
|
|
4915
4945
|
constructor(ws) {
|
|
4916
|
-
this.onmessage = void 0;
|
|
4917
|
-
this.onopen = void 0;
|
|
4918
|
-
this.onmessage = void 0;
|
|
4919
|
-
this.onerror = void 0;
|
|
4920
|
-
ws.onmessage = this.#handleOnMessage.bind(this);
|
|
4921
|
-
ws.onerror = this.#handleOnError.bind(this);
|
|
4922
|
-
ws.onclose = this.#handleOnClose.bind(this);
|
|
4923
|
-
ws.onopen = this.#handleOnOpen.bind(this);
|
|
4924
4946
|
ws.binaryType = "arraybuffer";
|
|
4925
4947
|
this.#ws = ws;
|
|
4926
4948
|
}
|
|
@@ -5557,12 +5579,13 @@ var DbConnectionImpl = class {
|
|
|
5557
5579
|
}
|
|
5558
5580
|
#makeReducers(def) {
|
|
5559
5581
|
const out = {};
|
|
5582
|
+
const writer = new BinaryWriter(1024);
|
|
5560
5583
|
for (const reducer of def.reducers) {
|
|
5561
5584
|
const reducerName = reducer.name;
|
|
5562
5585
|
const key = reducer.accessorName;
|
|
5563
5586
|
const { serialize: serializeArgs } = this.#reducerArgsSerializers[reducerName];
|
|
5564
5587
|
out[key] = (params) => {
|
|
5565
|
-
|
|
5588
|
+
writer.clear();
|
|
5566
5589
|
serializeArgs(writer, params);
|
|
5567
5590
|
const argsBuffer = writer.getBuffer();
|
|
5568
5591
|
return this.callReducer(reducerName, argsBuffer, params);
|
|
@@ -5572,12 +5595,13 @@ var DbConnectionImpl = class {
|
|
|
5572
5595
|
}
|
|
5573
5596
|
#makeProcedures(def) {
|
|
5574
5597
|
const out = {};
|
|
5598
|
+
const writer = new BinaryWriter(1024);
|
|
5575
5599
|
for (const procedure of def.procedures) {
|
|
5576
5600
|
const procedureName = procedure.name;
|
|
5577
5601
|
const key = procedure.accessorName;
|
|
5578
5602
|
const { serializeArgs, deserializeReturn } = this.#procedureSerializers[procedureName];
|
|
5579
5603
|
out[key] = (params) => {
|
|
5580
|
-
|
|
5604
|
+
writer.clear();
|
|
5581
5605
|
serializeArgs(writer, params);
|
|
5582
5606
|
const argsBuffer = writer.getBuffer();
|
|
5583
5607
|
return this.callProcedure(procedureName, argsBuffer).then((returnBuf) => {
|
|
@@ -5732,34 +5756,32 @@ var DbConnectionImpl = class {
|
|
|
5732
5756
|
}
|
|
5733
5757
|
return this.#mergeTableUpdates(updates);
|
|
5734
5758
|
}
|
|
5735
|
-
#sendEncoded(wsResolved, message) {
|
|
5736
|
-
stdbLogger(
|
|
5737
|
-
"trace",
|
|
5738
|
-
() => `Sending message to server: ${stringify(message)}`
|
|
5739
|
-
);
|
|
5740
|
-
const writer = new BinaryWriter(1024);
|
|
5741
|
-
ClientMessage.serialize(writer, message);
|
|
5742
|
-
const encoded = writer.getBuffer();
|
|
5743
|
-
wsResolved.send(encoded);
|
|
5744
|
-
}
|
|
5745
5759
|
#flushOutboundQueue(wsResolved) {
|
|
5746
|
-
if (!this.isActive || this.#outboundQueue.length === 0) {
|
|
5747
|
-
return;
|
|
5748
|
-
}
|
|
5749
5760
|
const pending = this.#outboundQueue.splice(0);
|
|
5750
5761
|
for (const message of pending) {
|
|
5751
|
-
|
|
5762
|
+
wsResolved.send(message);
|
|
5752
5763
|
}
|
|
5753
5764
|
}
|
|
5765
|
+
#clientMessageEncoder = new BinaryWriter(1024);
|
|
5754
5766
|
#sendMessage(message) {
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
this.#flushOutboundQueue(
|
|
5761
|
-
|
|
5762
|
-
|
|
5767
|
+
const writer = this.#clientMessageEncoder;
|
|
5768
|
+
writer.clear();
|
|
5769
|
+
ClientMessage.serialize(writer, message);
|
|
5770
|
+
const encoded = writer.getBuffer();
|
|
5771
|
+
if (this.ws && this.isActive) {
|
|
5772
|
+
if (this.#outboundQueue.length) this.#flushOutboundQueue(this.ws);
|
|
5773
|
+
stdbLogger(
|
|
5774
|
+
"trace",
|
|
5775
|
+
() => `Sending message to server: ${stringify(message)}`
|
|
5776
|
+
);
|
|
5777
|
+
this.ws.send(encoded);
|
|
5778
|
+
} else {
|
|
5779
|
+
stdbLogger(
|
|
5780
|
+
"trace",
|
|
5781
|
+
() => `Queuing message to server: ${stringify(message)}`
|
|
5782
|
+
);
|
|
5783
|
+
this.#outboundQueue.push(encoded.slice());
|
|
5784
|
+
}
|
|
5763
5785
|
}
|
|
5764
5786
|
#nextEventId() {
|
|
5765
5787
|
this.#eventId += 1;
|
|
@@ -6101,11 +6123,7 @@ var DbConnectionImpl = class {
|
|
|
6101
6123
|
* ```
|
|
6102
6124
|
*/
|
|
6103
6125
|
disconnect() {
|
|
6104
|
-
this.wsPromise.then((
|
|
6105
|
-
if (wsResolved) {
|
|
6106
|
-
wsResolved.close();
|
|
6107
|
-
}
|
|
6108
|
-
});
|
|
6126
|
+
this.wsPromise.then((ws) => ws?.close());
|
|
6109
6127
|
}
|
|
6110
6128
|
on(eventName, callback) {
|
|
6111
6129
|
this.#emitter.on(eventName, callback);
|
|
@@ -6135,17 +6153,45 @@ var DbConnectionImpl = class {
|
|
|
6135
6153
|
|
|
6136
6154
|
// src/lib/schema.ts
|
|
6137
6155
|
function tablesToSchema(ctx, tables) {
|
|
6156
|
+
const tableDefs = /* @__PURE__ */ Object.create(null);
|
|
6157
|
+
for (const [accName, schema2] of Object.entries(tables)) {
|
|
6158
|
+
tableDefs[accName] = tableToSchema(
|
|
6159
|
+
accName,
|
|
6160
|
+
schema2,
|
|
6161
|
+
schema2.tableDef(ctx, accName)
|
|
6162
|
+
);
|
|
6163
|
+
}
|
|
6138
6164
|
return {
|
|
6139
|
-
tables:
|
|
6140
|
-
Object.entries(tables).map(([accName, schema2]) => [
|
|
6141
|
-
accName,
|
|
6142
|
-
tableToSchema(accName, schema2, schema2.tableDef(ctx, accName))
|
|
6143
|
-
])
|
|
6144
|
-
)
|
|
6165
|
+
tables: tableDefs
|
|
6145
6166
|
};
|
|
6146
6167
|
}
|
|
6147
6168
|
function tableToSchema(accName, schema2, tableDef) {
|
|
6148
6169
|
const getColName = (i) => schema2.rowType.algebraicType.value.elements[i].name;
|
|
6170
|
+
const resolvedIndexes = tableDef.indexes.map(
|
|
6171
|
+
(idx) => {
|
|
6172
|
+
const accessorName = idx.accessorName;
|
|
6173
|
+
if (typeof accessorName !== "string" || accessorName.length === 0) {
|
|
6174
|
+
throw new TypeError(
|
|
6175
|
+
`Index '${idx.sourceName ?? "<unknown>"}' on table '${tableDef.sourceName}' is missing accessor name`
|
|
6176
|
+
);
|
|
6177
|
+
}
|
|
6178
|
+
const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value;
|
|
6179
|
+
const unique = tableDef.constraints.some(
|
|
6180
|
+
(c) => c.data.tag === "Unique" && c.data.value.columns.every((col) => columnIds.includes(col))
|
|
6181
|
+
);
|
|
6182
|
+
const algorithm = {
|
|
6183
|
+
BTree: "btree",
|
|
6184
|
+
Hash: "hash",
|
|
6185
|
+
Direct: "direct"
|
|
6186
|
+
}[idx.algorithm.tag];
|
|
6187
|
+
return {
|
|
6188
|
+
name: accessorName,
|
|
6189
|
+
unique,
|
|
6190
|
+
algorithm,
|
|
6191
|
+
columns: columnIds.map(getColName)
|
|
6192
|
+
};
|
|
6193
|
+
}
|
|
6194
|
+
);
|
|
6149
6195
|
return {
|
|
6150
6196
|
// For client,`schama.tableName` will always be there as canonical name.
|
|
6151
6197
|
// For module, if explicit name is not provided via `name`, accessor name will
|
|
@@ -6155,26 +6201,16 @@ function tableToSchema(accName, schema2, tableDef) {
|
|
|
6155
6201
|
columns: schema2.rowType.row,
|
|
6156
6202
|
// typed as T[i]['rowType']['row'] under TablesToSchema<T>
|
|
6157
6203
|
rowType: schema2.rowSpacetimeType,
|
|
6204
|
+
// Keep declarative indexes in their original shape for type-level consumers.
|
|
6205
|
+
indexes: schema2.idxs,
|
|
6158
6206
|
constraints: tableDef.constraints.map((c) => ({
|
|
6159
6207
|
name: c.sourceName,
|
|
6160
6208
|
constraint: "unique",
|
|
6161
6209
|
columns: c.data.value.columns.map(getColName)
|
|
6162
6210
|
})),
|
|
6163
|
-
//
|
|
6164
|
-
//
|
|
6165
|
-
|
|
6166
|
-
// We should stop lying about our types.
|
|
6167
|
-
indexes: tableDef.indexes.map((idx) => {
|
|
6168
|
-
const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value;
|
|
6169
|
-
return {
|
|
6170
|
-
name: idx.accessorName,
|
|
6171
|
-
unique: tableDef.constraints.some(
|
|
6172
|
-
(c) => c.data.value.columns.every((col) => columnIds.includes(col))
|
|
6173
|
-
),
|
|
6174
|
-
algorithm: idx.algorithm.tag.toLowerCase(),
|
|
6175
|
-
columns: columnIds.map(getColName)
|
|
6176
|
-
};
|
|
6177
|
-
}),
|
|
6211
|
+
// Expose resolved runtime indexes separately so runtime users don't have to
|
|
6212
|
+
// reinterpret `indexes` with unsafe casts.
|
|
6213
|
+
resolvedIndexes,
|
|
6178
6214
|
tableDef,
|
|
6179
6215
|
...tableDef.isEvent ? { isEvent: true } : {}
|
|
6180
6216
|
};
|
|
@@ -6998,6 +7034,14 @@ function table(opts, row, ..._) {
|
|
|
6998
7034
|
}
|
|
6999
7035
|
}
|
|
7000
7036
|
for (const indexOpts of userIndexes ?? []) {
|
|
7037
|
+
const accessor = indexOpts.accessor;
|
|
7038
|
+
if (typeof accessor !== "string" || accessor.length === 0) {
|
|
7039
|
+
const tableLabel = name ?? "<unnamed>";
|
|
7040
|
+
const indexLabel = indexOpts.name ?? "<unnamed>";
|
|
7041
|
+
throw new TypeError(
|
|
7042
|
+
`Index '${indexLabel}' on table '${tableLabel}' must define a non-empty 'accessor'`
|
|
7043
|
+
);
|
|
7044
|
+
}
|
|
7001
7045
|
let algorithm;
|
|
7002
7046
|
switch (indexOpts.algorithm) {
|
|
7003
7047
|
case "btree":
|
|
@@ -7018,7 +7062,7 @@ function table(opts, row, ..._) {
|
|
|
7018
7062
|
}
|
|
7019
7063
|
indexes.push({
|
|
7020
7064
|
sourceName: void 0,
|
|
7021
|
-
accessorName:
|
|
7065
|
+
accessorName: accessor,
|
|
7022
7066
|
algorithm,
|
|
7023
7067
|
canonicalName: indexOpts.name
|
|
7024
7068
|
});
|
|
@@ -7068,7 +7112,9 @@ function table(opts, row, ..._) {
|
|
|
7068
7112
|
isEvent
|
|
7069
7113
|
};
|
|
7070
7114
|
},
|
|
7071
|
-
|
|
7115
|
+
// Preserve the declared index options as runtime data so `tableToSchema`
|
|
7116
|
+
// can expose them without type-smuggling.
|
|
7117
|
+
idxs: userIndexes,
|
|
7072
7118
|
constraints,
|
|
7073
7119
|
schedule
|
|
7074
7120
|
};
|