trellis 3.2.2 → 3.2.3
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/browser/index.js +4 -4
- package/dist/{chunk-2W3MHTMG.js → chunk-2AACZRII.js} +122 -3
- package/dist/{chunk-H6JB3PZ3.js → chunk-5KSGGKET.js} +1 -1
- package/dist/{chunk-J2TXUFCZ.js → chunk-6RWGFC3N.js} +134 -20
- package/dist/{chunk-7ZFRVCUE.js → chunk-NWSW5YNS.js} +28 -14
- package/dist/{deploy-cli-C35HTITO.js → cli/deploy-cli.js} +5 -5
- package/dist/cli/index.js +5 -5
- package/dist/client/index.browser.js +2 -2
- package/dist/client/index.js +1 -1
- package/dist/client/sdk.browser.d.ts +28 -1
- package/dist/client/sdk.browser.d.ts.map +1 -1
- package/dist/client/sdk.browser.js +1 -1
- package/dist/client/sdk.js +1 -1
- package/dist/core/index.js +6 -6
- package/dist/db/index.js +5 -5
- package/dist/react/index.js +2 -2
- package/dist/react/schema-hooks.js +2 -2
- package/dist/server/cors.d.ts +13 -0
- package/dist/server/cors.d.ts.map +1 -0
- package/dist/server/deploy.d.ts +1 -1
- package/dist/server/deploy.d.ts.map +1 -1
- package/dist/server/deploy.js +9 -0
- package/dist/server/index.js +9 -9
- package/dist/server/server.d.ts.map +1 -1
- package/dist/{server-ZVWGLLRF.js → server-OGVWNDNK.js} +1 -1
- package/package.json +2 -2
- package/dist/chunk-FF36CQHZ.js +0 -61
- package/dist/chunk-IZX2PLIB.js +0 -1240
- package/dist/chunk-KIJITUZB.js +0 -419
- package/dist/chunk-SGMDTWJJ.js +0 -149
- package/dist/chunk-UQISRW6T.js +0 -203
- package/dist/db/trellis.css +0 -1
- package/dist/deploy-LQ7GUGJ5.js +0 -9
- package/dist/deploy-YNVG5E4E.js +0 -9
- package/dist/deploy-cli-24BCHAXY.js +0 -67
- package/dist/server-MB3OPSPI.js +0 -18
- package/dist/sprites-RU3E4XQN.js +0 -15
- package/dist/tenancy-NBLLGCNJ.js +0 -14
- /package/dist/{chunk-QB5ISE47.js → chunk-7DUMWO5L.js} +0 -0
package/dist/browser/index.js
CHANGED
|
@@ -3,6 +3,10 @@ import {
|
|
|
3
3
|
liveEntity,
|
|
4
4
|
liveQuery
|
|
5
5
|
} from "../chunk-J3WYZO3Q.js";
|
|
6
|
+
import {
|
|
7
|
+
FetchError,
|
|
8
|
+
TrellisDb
|
|
9
|
+
} from "../chunk-6RWGFC3N.js";
|
|
6
10
|
import "../chunk-WXSWA3MV.js";
|
|
7
11
|
import {
|
|
8
12
|
entityMutations
|
|
@@ -28,10 +32,6 @@ import {
|
|
|
28
32
|
resolveRelations,
|
|
29
33
|
whereCondition
|
|
30
34
|
} from "../chunk-JUEMDWLU.js";
|
|
31
|
-
import {
|
|
32
|
-
FetchError,
|
|
33
|
-
TrellisDb
|
|
34
|
-
} from "../chunk-J2TXUFCZ.js";
|
|
35
35
|
import {
|
|
36
36
|
BroadcastChannelTransport,
|
|
37
37
|
DEFAULT_MAX_RECORDS,
|
|
@@ -682,6 +682,55 @@ function computeDiff(prev, next) {
|
|
|
682
682
|
return { added, updated, removed };
|
|
683
683
|
}
|
|
684
684
|
|
|
685
|
+
// src/server/cors.ts
|
|
686
|
+
var DEFAULT_METHODS = "GET, POST, PUT, DELETE, OPTIONS";
|
|
687
|
+
var DEFAULT_HEADERS = "Content-Type, Authorization";
|
|
688
|
+
function corsEnabledForConfig(apiKey) {
|
|
689
|
+
return Boolean(process.env.TRELLIS_CORS_ORIGINS) || Boolean(apiKey);
|
|
690
|
+
}
|
|
691
|
+
function allowedOrigins() {
|
|
692
|
+
const raw = process.env.TRELLIS_CORS_ORIGINS?.trim();
|
|
693
|
+
if (!raw || raw === "*") return "*";
|
|
694
|
+
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
695
|
+
}
|
|
696
|
+
function corsHeaders(req) {
|
|
697
|
+
const origins = allowedOrigins();
|
|
698
|
+
const requestOrigin = req.headers.get("Origin");
|
|
699
|
+
let allowOrigin = "*";
|
|
700
|
+
if (origins !== "*") {
|
|
701
|
+
if (requestOrigin && origins.includes(requestOrigin)) {
|
|
702
|
+
allowOrigin = requestOrigin;
|
|
703
|
+
} else if (origins.length === 1) {
|
|
704
|
+
allowOrigin = origins[0];
|
|
705
|
+
} else {
|
|
706
|
+
allowOrigin = origins[0] ?? "*";
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return {
|
|
710
|
+
"Access-Control-Allow-Origin": allowOrigin,
|
|
711
|
+
"Access-Control-Allow-Methods": DEFAULT_METHODS,
|
|
712
|
+
"Access-Control-Allow-Headers": DEFAULT_HEADERS,
|
|
713
|
+
Vary: "Origin"
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
function withCors(req, res) {
|
|
717
|
+
const headers = new Headers(res.headers);
|
|
718
|
+
for (const [key, value] of Object.entries(corsHeaders(req))) {
|
|
719
|
+
headers.set(key, value);
|
|
720
|
+
}
|
|
721
|
+
return new Response(res.body, {
|
|
722
|
+
status: res.status,
|
|
723
|
+
statusText: res.statusText,
|
|
724
|
+
headers
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
function corsPreflightResponse(req) {
|
|
728
|
+
return new Response(null, {
|
|
729
|
+
status: 204,
|
|
730
|
+
headers: corsHeaders(req)
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
|
|
685
734
|
// src/server/server.ts
|
|
686
735
|
var __moduleDir = import.meta.dir ?? dirname(fileURLToPath(import.meta.url));
|
|
687
736
|
async function startServer(opts) {
|
|
@@ -698,7 +747,8 @@ function buildServerContext(opts) {
|
|
|
698
747
|
};
|
|
699
748
|
const meter = new UsageMeter();
|
|
700
749
|
const subs = new SubscriptionManager(pool, permissions ?? null, meter);
|
|
701
|
-
const
|
|
750
|
+
const enableCors = corsEnabledForConfig(config.apiKey);
|
|
751
|
+
const handleHttpInner = async (req) => {
|
|
702
752
|
const url = new URL(req.url);
|
|
703
753
|
const path = url.pathname;
|
|
704
754
|
const auth = await resolveAuth(
|
|
@@ -721,9 +771,30 @@ function buildServerContext(opts) {
|
|
|
721
771
|
return json(err.toResponse(), 403);
|
|
722
772
|
}
|
|
723
773
|
const msg = err instanceof Error ? err.message : String(err);
|
|
724
|
-
|
|
774
|
+
if (process.env.TRELLIS_DEBUG) {
|
|
775
|
+
console.error(
|
|
776
|
+
`[trellis] ${req.method} ${path} \u2192 500:`,
|
|
777
|
+
msg
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
return json(
|
|
781
|
+
{
|
|
782
|
+
error: "Internal Server Error",
|
|
783
|
+
message: msg,
|
|
784
|
+
method: req.method,
|
|
785
|
+
path
|
|
786
|
+
},
|
|
787
|
+
500
|
|
788
|
+
);
|
|
725
789
|
}
|
|
726
790
|
};
|
|
791
|
+
const handleHttp = async (req) => {
|
|
792
|
+
if (enableCors && req.method === "OPTIONS") {
|
|
793
|
+
return corsPreflightResponse(req);
|
|
794
|
+
}
|
|
795
|
+
const res = await handleHttpInner(req);
|
|
796
|
+
return enableCors ? withCors(req, res) : res;
|
|
797
|
+
};
|
|
727
798
|
return { port, authConfig, subs, handleHttp };
|
|
728
799
|
}
|
|
729
800
|
async function startServerNode(opts) {
|
|
@@ -964,8 +1035,56 @@ async function handleQuery(req, auth, tenantId, ctx) {
|
|
|
964
1035
|
executionTime: result.executionTime
|
|
965
1036
|
});
|
|
966
1037
|
}
|
|
1038
|
+
async function readJsonObject(req, route2) {
|
|
1039
|
+
const raw = await req.text();
|
|
1040
|
+
if (!raw.trim()) {
|
|
1041
|
+
if (process.env.TRELLIS_DEBUG) {
|
|
1042
|
+
console.warn(`[trellis] ${req.method} ${route2}: empty request body`);
|
|
1043
|
+
}
|
|
1044
|
+
return {
|
|
1045
|
+
ok: false,
|
|
1046
|
+
response: json(
|
|
1047
|
+
{
|
|
1048
|
+
error: "Bad Request",
|
|
1049
|
+
message: "Request body is empty \u2014 client may not have sent JSON (common on iOS HTTP dev)",
|
|
1050
|
+
method: req.method,
|
|
1051
|
+
path: route2,
|
|
1052
|
+
bodyBytes: 0
|
|
1053
|
+
},
|
|
1054
|
+
400
|
|
1055
|
+
)
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
try {
|
|
1059
|
+
const data = JSON.parse(raw);
|
|
1060
|
+
return { ok: true, data };
|
|
1061
|
+
} catch (err) {
|
|
1062
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1063
|
+
if (process.env.TRELLIS_DEBUG) {
|
|
1064
|
+
console.warn(
|
|
1065
|
+
`[trellis] ${req.method} ${route2}: invalid JSON (${raw.length}B):`,
|
|
1066
|
+
msg
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
return {
|
|
1070
|
+
ok: false,
|
|
1071
|
+
response: json(
|
|
1072
|
+
{
|
|
1073
|
+
error: "Bad Request",
|
|
1074
|
+
message: `Invalid JSON: ${msg}`,
|
|
1075
|
+
method: req.method,
|
|
1076
|
+
path: route2,
|
|
1077
|
+
bodyBytes: raw.length
|
|
1078
|
+
},
|
|
1079
|
+
400
|
|
1080
|
+
)
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
967
1084
|
async function handleCreateOntology(req, auth, tenantId, ctx) {
|
|
968
|
-
const
|
|
1085
|
+
const parsed = await readJsonObject(req, "/ontologies");
|
|
1086
|
+
if (!parsed.ok) return parsed.response;
|
|
1087
|
+
const schema = parsed.data;
|
|
969
1088
|
if (!schema || !schema["@id"] || !Array.isArray(schema.fields)) {
|
|
970
1089
|
return json(
|
|
971
1090
|
{ error: "A SchemaDefinition (with @id and fields) is required" },
|
|
@@ -7,6 +7,37 @@ function browserOnlyRemoteError(feature) {
|
|
|
7
7
|
`${feature} is not available in browser bundles. Use remote mode with \`new TrellisDb({ url })\`, or import \`trellis/client\` in Node.`
|
|
8
8
|
);
|
|
9
9
|
}
|
|
10
|
+
function randomId() {
|
|
11
|
+
if (typeof globalThis.crypto?.randomUUID === "function") {
|
|
12
|
+
return globalThis.crypto.randomUUID();
|
|
13
|
+
}
|
|
14
|
+
return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 11)}`;
|
|
15
|
+
}
|
|
16
|
+
function needsXhrForBody() {
|
|
17
|
+
if (typeof globalThis.window !== "undefined" && window.__TRELLIS_NATIVE_HTTP__) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
if (typeof navigator === "undefined") return false;
|
|
21
|
+
const ua = navigator.userAgent;
|
|
22
|
+
if (/iPad|iPhone|iPod/i.test(ua)) return true;
|
|
23
|
+
if (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) return true;
|
|
24
|
+
if (/AppleWebKit/i.test(ua) && /KHTML, like Gecko\)/i.test(ua) && !/Safari\/|Chrome\/|Chromium\/|Edg\/|Version\//i.test(ua)) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
function xhrRequest(method, url, headers, body) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const xhr = new XMLHttpRequest();
|
|
32
|
+
xhr.open(method, url);
|
|
33
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
34
|
+
xhr.setRequestHeader(key, value);
|
|
35
|
+
}
|
|
36
|
+
xhr.onload = () => resolve({ status: xhr.status, text: xhr.responseText });
|
|
37
|
+
xhr.onerror = () => reject(new Error(`XHR network error on ${method} ${url}`));
|
|
38
|
+
xhr.send(body);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
10
41
|
var TrellisDb = class {
|
|
11
42
|
opts;
|
|
12
43
|
_ws = null;
|
|
@@ -101,10 +132,21 @@ var TrellisDb = class {
|
|
|
101
132
|
*/
|
|
102
133
|
async registerType(schema) {
|
|
103
134
|
const def = "@id" in schema ? schema : schema.definition;
|
|
135
|
+
const label = def?.label ?? (def?.["@id"] ? String(def["@id"]).replace(/^trellis:/, "") : "unknown");
|
|
136
|
+
if (!def?.["@id"]) {
|
|
137
|
+
throw new Error(`registerType(${label}): schema is missing a definition with @id`);
|
|
138
|
+
}
|
|
104
139
|
try {
|
|
105
140
|
await this._fetch("POST", "/ontologies", def);
|
|
106
141
|
} catch (err) {
|
|
107
142
|
if (err instanceof FetchError && err.status === 409) return;
|
|
143
|
+
if (err instanceof FetchError) {
|
|
144
|
+
const serverMsg = typeof err.body?.message === "string" ? String(err.body.message) : err.message;
|
|
145
|
+
throw new FetchError(err.status, serverMsg, err.body, {
|
|
146
|
+
...err.context,
|
|
147
|
+
operation: `registerType(${label})`
|
|
148
|
+
});
|
|
149
|
+
}
|
|
108
150
|
throw err;
|
|
109
151
|
}
|
|
110
152
|
}
|
|
@@ -176,7 +218,7 @@ var TrellisDb = class {
|
|
|
176
218
|
* Callback is fired immediately with the initial result, then on every update.
|
|
177
219
|
*/
|
|
178
220
|
subscribe(eql, callback, opts) {
|
|
179
|
-
const subId = `sub_${
|
|
221
|
+
const subId = `sub_${randomId()}`;
|
|
180
222
|
this._subCallbacks.set(subId, callback);
|
|
181
223
|
this._ensureWs().then((ws) => {
|
|
182
224
|
ws.send(
|
|
@@ -184,6 +226,7 @@ var TrellisDb = class {
|
|
|
184
226
|
type: "subscribe",
|
|
185
227
|
id: subId,
|
|
186
228
|
query: eql,
|
|
229
|
+
...this.opts.tenantId ? { tenantId: this.opts.tenantId } : {},
|
|
187
230
|
...opts?.entityType ? { entityType: opts.entityType } : {},
|
|
188
231
|
...opts?.resolve ? { resolve: opts.resolve } : {}
|
|
189
232
|
})
|
|
@@ -214,23 +257,69 @@ var TrellisDb = class {
|
|
|
214
257
|
// -------------------------------------------------------------------------
|
|
215
258
|
// Private
|
|
216
259
|
// -------------------------------------------------------------------------
|
|
260
|
+
/**
|
|
261
|
+
* Tenant isolation, not authorization: when `tenantId` is supplied out-of-band
|
|
262
|
+
* (not bound to the JWT), the server trusts the query param. Safe for ephemeral
|
|
263
|
+
* showcase rooms with unguessable ids; real multi-tenant auth must bind the
|
|
264
|
+
* tenant to the auth token instead. Skipped when the JWT already carries it.
|
|
265
|
+
*/
|
|
266
|
+
_applyTenant(path) {
|
|
267
|
+
const tenantId = this.opts.tenantId;
|
|
268
|
+
if (!tenantId) return path;
|
|
269
|
+
const sep = path.includes("?") ? "&" : "?";
|
|
270
|
+
return `${path}${sep}tenantId=${encodeURIComponent(tenantId)}`;
|
|
271
|
+
}
|
|
217
272
|
async _fetch(method, path, body) {
|
|
218
|
-
const url = `${this.opts.url}${path}`;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
273
|
+
const url = `${this.opts.url}${this._applyTenant(path)}`;
|
|
274
|
+
let jsonBody;
|
|
275
|
+
if (body !== void 0) {
|
|
276
|
+
jsonBody = JSON.stringify(body);
|
|
277
|
+
if (jsonBody === void 0) {
|
|
278
|
+
throw new Error(`Request body is not JSON-serializable (${method} ${path})`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const headers = {
|
|
282
|
+
"Content-Type": "application/json",
|
|
283
|
+
...this.opts.apiKey ? { Authorization: `Bearer ${this.opts.apiKey}` } : {}
|
|
284
|
+
};
|
|
285
|
+
const transport = jsonBody !== void 0 && needsXhrForBody() ? "xhr" : "fetch";
|
|
286
|
+
headers["X-Trellis-Transport"] = transport;
|
|
287
|
+
const bodyBytes = jsonBody ? new TextEncoder().encode(jsonBody).byteLength : 0;
|
|
288
|
+
let status;
|
|
289
|
+
let text;
|
|
290
|
+
if (transport === "xhr" && jsonBody !== void 0) {
|
|
291
|
+
({ status, text } = await xhrRequest(method, url, headers, jsonBody));
|
|
292
|
+
} else {
|
|
293
|
+
const res = await fetch(url, {
|
|
294
|
+
method,
|
|
295
|
+
headers,
|
|
296
|
+
body: jsonBody
|
|
297
|
+
});
|
|
298
|
+
status = res.status;
|
|
299
|
+
text = await res.text();
|
|
300
|
+
}
|
|
301
|
+
let data = null;
|
|
302
|
+
if (text) {
|
|
303
|
+
try {
|
|
304
|
+
data = JSON.parse(text);
|
|
305
|
+
} catch {
|
|
306
|
+
data = { raw: text };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (status < 200 || status >= 300) {
|
|
310
|
+
const server = data;
|
|
311
|
+
const message = typeof server?.message === "string" && server.message || typeof server?.error === "string" && server.error || "request failed";
|
|
312
|
+
const err = new FetchError(status, message, data, {
|
|
313
|
+
method,
|
|
314
|
+
path,
|
|
315
|
+
url,
|
|
316
|
+
requestBodyBytes: bodyBytes,
|
|
317
|
+
responseBytes: text.length,
|
|
318
|
+
transport
|
|
319
|
+
});
|
|
320
|
+
console.error("[trellis]", err.toString());
|
|
321
|
+
throw err;
|
|
322
|
+
}
|
|
234
323
|
return data;
|
|
235
324
|
}
|
|
236
325
|
_ensureWs() {
|
|
@@ -274,12 +363,37 @@ var TrellisDb = class {
|
|
|
274
363
|
return this._wsPromise;
|
|
275
364
|
}
|
|
276
365
|
};
|
|
277
|
-
var FetchError = class extends Error {
|
|
278
|
-
constructor(status, message, body) {
|
|
279
|
-
super(
|
|
366
|
+
var FetchError = class _FetchError extends Error {
|
|
367
|
+
constructor(status, message, body, context = {}) {
|
|
368
|
+
super(_FetchError.format(status, message, context));
|
|
280
369
|
this.status = status;
|
|
281
370
|
this.body = body;
|
|
282
371
|
this.name = "FetchError";
|
|
372
|
+
this.context = context;
|
|
373
|
+
}
|
|
374
|
+
context;
|
|
375
|
+
static format(status, message, ctx) {
|
|
376
|
+
const parts = [`HTTP ${status}`];
|
|
377
|
+
if (ctx.operation) parts.push(ctx.operation);
|
|
378
|
+
if (ctx.method && ctx.path) parts.push(`${ctx.method} ${ctx.path}`);
|
|
379
|
+
parts.push(message);
|
|
380
|
+
if (ctx.requestBodyBytes !== void 0) {
|
|
381
|
+
parts.push(`sent ${ctx.requestBodyBytes}B`);
|
|
382
|
+
}
|
|
383
|
+
if (ctx.responseBytes !== void 0) {
|
|
384
|
+
parts.push(`response ${ctx.responseBytes}B`);
|
|
385
|
+
}
|
|
386
|
+
if (ctx.transport) parts.push(ctx.transport);
|
|
387
|
+
return parts.join(" \xB7 ");
|
|
388
|
+
}
|
|
389
|
+
toString() {
|
|
390
|
+
const extra = [];
|
|
391
|
+
if (this.body && typeof this.body === "object") {
|
|
392
|
+
const b = this.body;
|
|
393
|
+
if (typeof b.path === "string") extra.push(`server ${b.method} ${b.path}`);
|
|
394
|
+
if (typeof b.bodyBytes === "number") extra.push(`server saw ${b.bodyBytes}B`);
|
|
395
|
+
}
|
|
396
|
+
return extra.length ? `${this.message} (${extra.join(", ")})` : this.message;
|
|
283
397
|
}
|
|
284
398
|
};
|
|
285
399
|
|
|
@@ -10,13 +10,12 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
updateConfig
|
|
12
12
|
} from "./chunk-JA7AIHRK.js";
|
|
13
|
-
import {
|
|
14
|
-
__require
|
|
15
|
-
} from "./chunk-KFQGP6VL.js";
|
|
16
13
|
|
|
17
14
|
// src/server/deploy.ts
|
|
15
|
+
import { execFile } from "child_process";
|
|
18
16
|
import { existsSync, writeFileSync, mkdirSync } from "fs";
|
|
19
17
|
import { join, resolve } from "path";
|
|
18
|
+
import { promisify } from "util";
|
|
20
19
|
|
|
21
20
|
// src/server/deploy-meta.ts
|
|
22
21
|
var DEPLOY_NAME_RE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
@@ -109,16 +108,22 @@ async function deploy(opts) {
|
|
|
109
108
|
if (!bunPath.includes("bun")) {
|
|
110
109
|
throw new Error(`Bun install failed on sprite ${name}: ${bunPath || "(no output)"}`);
|
|
111
110
|
}
|
|
112
|
-
onProgress("Starting server...");
|
|
113
|
-
await runSpriteExec(
|
|
114
|
-
name,
|
|
115
|
-
'pkill -f "/home/sprite/trellis-db/server.js" 2>/dev/null || true'
|
|
116
|
-
).catch(() => {
|
|
117
|
-
});
|
|
111
|
+
onProgress("Starting server (sprite-env service)...");
|
|
118
112
|
const bun = bunPath.trim().split("\n").pop().trim();
|
|
119
113
|
await runSpriteExec(
|
|
120
114
|
name,
|
|
121
|
-
`
|
|
115
|
+
`
|
|
116
|
+
export PATH="$HOME/.bun/bin:$PATH"
|
|
117
|
+
ENV="/.sprite/bin/sprite-env"
|
|
118
|
+
BUN="${bun}"
|
|
119
|
+
$ENV services delete trellis-db 2>/dev/null || true
|
|
120
|
+
$ENV services create trellis-db \\
|
|
121
|
+
--cmd "$BUN" \\
|
|
122
|
+
--args run,server.js \\
|
|
123
|
+
--dir /home/sprite/trellis-db \\
|
|
124
|
+
--http-port ${listenPort} \\
|
|
125
|
+
--no-stream
|
|
126
|
+
`.trim()
|
|
122
127
|
);
|
|
123
128
|
onProgress("Waiting for health check...");
|
|
124
129
|
await waitForDeployHealth(url, 6e4);
|
|
@@ -162,8 +167,6 @@ function generateSecret(prefix) {
|
|
|
162
167
|
return `${prefix}${b64}`;
|
|
163
168
|
}
|
|
164
169
|
async function runBun(args) {
|
|
165
|
-
const { execFile } = __require("child_process");
|
|
166
|
-
const { promisify } = __require("util");
|
|
167
170
|
const execFileAsync = promisify(execFile);
|
|
168
171
|
try {
|
|
169
172
|
await execFileAsync("bun", args);
|
|
@@ -173,10 +176,21 @@ async function runBun(args) {
|
|
|
173
176
|
);
|
|
174
177
|
}
|
|
175
178
|
}
|
|
179
|
+
function resolveTrellisImports() {
|
|
180
|
+
const root = process.env.TRELLIS_NODE_ROOT?.trim();
|
|
181
|
+
if (root) {
|
|
182
|
+
return {
|
|
183
|
+
server: join(root, "dist/server/index.js").replace(/\\/g, "/"),
|
|
184
|
+
client: join(root, "dist/client/index.js").replace(/\\/g, "/")
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return { server: "trellis/server", client: "trellis/client" };
|
|
188
|
+
}
|
|
176
189
|
function generateServerEntrypoint(opts) {
|
|
190
|
+
const { server, client } = resolveTrellisImports();
|
|
177
191
|
return `
|
|
178
|
-
import { TenantPool, startServer } from '
|
|
179
|
-
import { readConfig, defaultLocalConfig, writeConfig } from '
|
|
192
|
+
import { TenantPool, startServer } from '${server}';
|
|
193
|
+
import { readConfig, defaultLocalConfig, writeConfig } from '${client}';
|
|
180
194
|
import { join } from 'path';
|
|
181
195
|
import { existsSync } from 'fs';
|
|
182
196
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DeployNameError,
|
|
3
3
|
deploy
|
|
4
|
-
} from "
|
|
5
|
-
import "
|
|
4
|
+
} from "../chunk-NWSW5YNS.js";
|
|
5
|
+
import "../chunk-CAG4FULI.js";
|
|
6
6
|
import {
|
|
7
7
|
configPath
|
|
8
|
-
} from "
|
|
9
|
-
import "
|
|
8
|
+
} from "../chunk-JA7AIHRK.js";
|
|
9
|
+
import "../chunk-KFQGP6VL.js";
|
|
10
10
|
|
|
11
11
|
// src/cli/deploy-cli.ts
|
|
12
12
|
import chalk from "chalk";
|
|
@@ -35,7 +35,7 @@ function printDeploySuccess(result, configDir, stub) {
|
|
|
35
35
|
async function runDeployCli(opts) {
|
|
36
36
|
const configDir = opts.configDir ?? ".";
|
|
37
37
|
const port = opts.port === void 0 ? void 0 : typeof opts.port === "string" ? parseInt(opts.port, 10) : opts.port;
|
|
38
|
-
const { readConfig } = await import("
|
|
38
|
+
const { readConfig } = await import("../config-PFTP67TR.js");
|
|
39
39
|
const config = readConfig(configDir);
|
|
40
40
|
const label = opts.stub ? "Stub deploy" : "Deploying to Sprites";
|
|
41
41
|
console.log(chalk.bold(`${label}: ${opts.name}...`));
|
package/dist/cli/index.js
CHANGED
|
@@ -4467,7 +4467,7 @@ db.command("init").description("Initialize a new Trellis DB in the current direc
|
|
|
4467
4467
|
db.command("serve").description("Start the Trellis DB HTTP + WebSocket server").option("-p, --port <port>", "Override port from config").option("--config-dir <dir>", "Directory containing .trellis-db.json", ".").action(async (opts) => {
|
|
4468
4468
|
const { readConfig } = await import("../config-PFTP67TR.js");
|
|
4469
4469
|
const { TenantPool } = await import("../tenancy-POMWQP6M.js");
|
|
4470
|
-
const { startServer } = await import("../server-
|
|
4470
|
+
const { startServer } = await import("../server-OGVWNDNK.js");
|
|
4471
4471
|
const config = readConfig(opts.configDir);
|
|
4472
4472
|
if (!config) {
|
|
4473
4473
|
console.error(
|
|
@@ -4489,7 +4489,7 @@ db.command("serve").description("Start the Trellis DB HTTP + WebSocket server").
|
|
|
4489
4489
|
backendOpts ? { backend: backendOpts } : void 0
|
|
4490
4490
|
);
|
|
4491
4491
|
await pool.preload(DEFAULT_TENANT);
|
|
4492
|
-
const { startServerCrossRuntime } = await import("../server-
|
|
4492
|
+
const { startServerCrossRuntime } = await import("../server-OGVWNDNK.js");
|
|
4493
4493
|
const server = await startServerCrossRuntime({ port, config, pool });
|
|
4494
4494
|
console.log(chalk4.green(`\u2713 Trellis DB running`));
|
|
4495
4495
|
console.log(chalk4.dim(` URL: http://localhost:${port}`));
|
|
@@ -4621,7 +4621,7 @@ function registerDeployOptions(cmd) {
|
|
|
4621
4621
|
);
|
|
4622
4622
|
}
|
|
4623
4623
|
async function handleDeployCommand(opts) {
|
|
4624
|
-
const { runDeployCli } = await import("
|
|
4624
|
+
const { runDeployCli } = await import("./deploy-cli.js");
|
|
4625
4625
|
await runDeployCli(opts);
|
|
4626
4626
|
}
|
|
4627
4627
|
registerDeployOptions(
|
|
@@ -4644,7 +4644,7 @@ async function getSpriteName(spriteOption) {
|
|
|
4644
4644
|
vmProgram.command("create <name>").description("Create a new Sprite and deploy Trellis DB").option("-k, --api-key <key>", "API key (auto-generated if omitted)").option("-p, --port <port>", "Port (default: 3000)", "3000").action(async (name, cmdOpts) => {
|
|
4645
4645
|
const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
|
|
4646
4646
|
const { trackSprite } = await import("../vm-config-JI4OXKDQ.js");
|
|
4647
|
-
const { deploy } = await import("../deploy
|
|
4647
|
+
const { deploy } = await import("../server/deploy.js");
|
|
4648
4648
|
try {
|
|
4649
4649
|
await assertSpriteCli();
|
|
4650
4650
|
console.log(`Creating Sprite: ${name}...`);
|
|
@@ -4950,7 +4950,7 @@ vmProgram.command("status").description("Show detailed status of the active Spri
|
|
|
4950
4950
|
vmProgram.command("code [name]").description("Create Sprite, deploy Trellis, open in browser").action(async (nameOpt) => {
|
|
4951
4951
|
const { runSpriteCmd, assertSpriteCli } = await import("../sprites-KQGTGM6W.js");
|
|
4952
4952
|
const { loadVmConfig, trackSprite, getActiveSprite } = await import("../vm-config-JI4OXKDQ.js");
|
|
4953
|
-
const { deploy } = await import("../deploy
|
|
4953
|
+
const { deploy } = await import("../server/deploy.js");
|
|
4954
4954
|
const openUrl = (url) => {
|
|
4955
4955
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : null;
|
|
4956
4956
|
if (!cmd) {
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
liveEntity,
|
|
4
4
|
liveQuery
|
|
5
5
|
} from "../chunk-J3WYZO3Q.js";
|
|
6
|
-
import "../chunk-JUEMDWLU.js";
|
|
7
6
|
import {
|
|
8
7
|
FetchError,
|
|
9
8
|
TrellisDb
|
|
10
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-6RWGFC3N.js";
|
|
10
|
+
import "../chunk-JUEMDWLU.js";
|
|
11
11
|
import {
|
|
12
12
|
BatchSignal,
|
|
13
13
|
Signal
|
package/dist/client/index.js
CHANGED
|
@@ -15,6 +15,14 @@ export interface SubscribeOptions {
|
|
|
15
15
|
entityType?: string;
|
|
16
16
|
resolve?: ResolveSpec;
|
|
17
17
|
}
|
|
18
|
+
declare global {
|
|
19
|
+
interface Window {
|
|
20
|
+
/** Set by host app when WKWebView drops fetch POST bodies (XHR fallback). */
|
|
21
|
+
__TRELLIS_USE_XHR__?: boolean;
|
|
22
|
+
/** Host patched fetch via Tauri plugin-http — always use fetch, never XHR. */
|
|
23
|
+
__TRELLIS_NATIVE_HTTP__?: boolean;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
18
26
|
export declare class TrellisDb {
|
|
19
27
|
private opts;
|
|
20
28
|
private _ws;
|
|
@@ -93,12 +101,31 @@ export declare class TrellisDb {
|
|
|
93
101
|
* Close open client resources.
|
|
94
102
|
*/
|
|
95
103
|
close(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Tenant isolation, not authorization: when `tenantId` is supplied out-of-band
|
|
106
|
+
* (not bound to the JWT), the server trusts the query param. Safe for ephemeral
|
|
107
|
+
* showcase rooms with unguessable ids; real multi-tenant auth must bind the
|
|
108
|
+
* tenant to the auth token instead. Skipped when the JWT already carries it.
|
|
109
|
+
*/
|
|
110
|
+
private _applyTenant;
|
|
96
111
|
private _fetch;
|
|
97
112
|
private _ensureWs;
|
|
98
113
|
}
|
|
114
|
+
export interface FetchErrorContext {
|
|
115
|
+
method?: string;
|
|
116
|
+
path?: string;
|
|
117
|
+
url?: string;
|
|
118
|
+
operation?: string;
|
|
119
|
+
requestBodyBytes?: number;
|
|
120
|
+
responseBytes?: number;
|
|
121
|
+
transport?: 'fetch' | 'xhr';
|
|
122
|
+
}
|
|
99
123
|
export declare class FetchError extends Error {
|
|
100
124
|
status: number;
|
|
101
125
|
body?: unknown | undefined;
|
|
102
|
-
|
|
126
|
+
readonly context: FetchErrorContext;
|
|
127
|
+
constructor(status: number, message: string, body?: unknown | undefined, context?: FetchErrorContext);
|
|
128
|
+
static format(status: number, message: string, ctx: FetchErrorContext): string;
|
|
129
|
+
toString(): string;
|
|
103
130
|
}
|
|
104
131
|
//# sourceMappingURL=sdk.browser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.browser.d.ts","sourceRoot":"","sources":["../../src/client/sdk.browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EAEpB,gBAAgB,EAEhB,YAAY,EACb,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,sBAAsB,EACtB,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"sdk.browser.d.ts","sourceRoot":"","sources":["../../src/client/sdk.browser.ts"],"names":[],"mappings":"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"}
|
package/dist/client/sdk.js
CHANGED
package/dist/core/index.js
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SqlJsKernelBackend
|
|
3
|
-
} from "../chunk-LNUIGRDZ.js";
|
|
4
|
-
import {
|
|
5
|
-
createKernelBackend
|
|
6
|
-
} from "../chunk-FKQO5A3H.js";
|
|
7
1
|
import {
|
|
8
2
|
OntologyRegistry,
|
|
9
3
|
agentOntology,
|
|
@@ -14,6 +8,12 @@ import {
|
|
|
14
8
|
validateEntity,
|
|
15
9
|
validateStore
|
|
16
10
|
} from "../chunk-YCM7ZYEZ.js";
|
|
11
|
+
import {
|
|
12
|
+
SqlJsKernelBackend
|
|
13
|
+
} from "../chunk-LNUIGRDZ.js";
|
|
14
|
+
import {
|
|
15
|
+
createKernelBackend
|
|
16
|
+
} from "../chunk-FKQO5A3H.js";
|
|
17
17
|
import {
|
|
18
18
|
ExprEvaluator,
|
|
19
19
|
attachStandardMiddleware,
|