trellis 3.2.0 → 3.2.2
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/CHANGELOG.md +7 -0
- package/README.md +61 -171
- package/dist/browser/index.d.ts +18 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +95 -0
- package/dist/{chunk-3ETIIPPB.js → chunk-2W3MHTMG.js} +190 -27
- package/dist/{chunk-MBNBTJCR.js → chunk-6GEZ6DN5.js} +2 -2
- package/dist/chunk-7ZFRVCUE.js +211 -0
- package/dist/chunk-CAG4FULI.js +121 -0
- package/dist/{chunk-GD5QJXSS.js → chunk-FWRS4CSC.js} +2 -2
- package/dist/{chunk-36VSSTL7.js → chunk-GU374KWZ.js} +1 -1
- package/dist/{chunk-3GDRZTAW.js → chunk-H6JB3PZ3.js} +1 -1
- package/dist/{chunk-ZHVI7BQN.js → chunk-IZX2PLIB.js} +191 -28
- package/dist/chunk-J2TXUFCZ.js +289 -0
- package/dist/{chunk-BJ7EZ7FP.js → chunk-JHHEXEDM.js} +17 -0
- package/dist/{chunk-X762XWVC.js → chunk-KIJITUZB.js} +1 -1
- package/dist/{chunk-7WQGTFVJ.js → chunk-L5N5PR2S.js} +130 -75
- package/dist/{chunk-BXSTJVE3.js → chunk-N6MYZT4O.js} +2 -1
- package/dist/{chunk-KKDRMIV6.js → chunk-QB5ISE47.js} +1 -1
- package/dist/{chunk-HO4TURXW.js → chunk-S3XLFZ27.js} +28 -11
- package/dist/{chunk-BQBUVMRN.js → chunk-S6GBJ2ZB.js} +25 -14
- package/dist/{chunk-IUWVEEOX.js → chunk-SGMDTWJJ.js} +4 -0
- package/dist/{chunk-FZVCXDYW.js → chunk-UQISRW6T.js} +65 -12
- package/dist/{chunk-B3ZIFA2O.js → chunk-VBYUTRXX.js} +1 -1
- package/dist/cli/deploy-cli.d.ts +18 -0
- package/dist/cli/deploy-cli.d.ts.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +153 -100
- package/dist/client/index.browser.d.ts +29 -0
- package/dist/client/index.browser.d.ts.map +1 -0
- package/dist/client/index.browser.js +64 -0
- package/dist/client/index.js +10 -10
- package/dist/client/sdk.browser.d.ts +104 -0
- package/dist/client/sdk.browser.d.ts.map +1 -0
- package/dist/{sdk-LZ7W3EEY.js → client/sdk.browser.js} +2 -2
- package/dist/client/sdk.js +1 -1
- package/dist/core/index.js +6 -6
- package/dist/db/index.js +18 -18
- package/dist/db/inspector.js +6 -6
- package/dist/db/trellis.css +1 -1
- package/dist/decisions/index.js +2 -2
- package/dist/deploy-LQ7GUGJ5.js +9 -0
- package/dist/{deploy-66EC752W.js → deploy-YNVG5E4E.js} +1 -1
- package/dist/deploy-cli-24BCHAXY.js +67 -0
- package/dist/deploy-cli-C35HTITO.js +67 -0
- package/dist/embeddings/auto-embed.d.ts.map +1 -1
- package/dist/embeddings/index.js +1 -1
- package/dist/embeddings/store.d.ts.map +1 -1
- package/dist/engine.d.ts +27 -7
- package/dist/engine.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/react/index.js +2 -2
- package/dist/react/schema-hooks.js +7 -7
- package/dist/{remote-manager-SG545WNY.js → remote-manager-ODE3T2KR.js} +5 -5
- package/dist/scaffold/seed.d.ts.map +1 -1
- package/dist/scaffold/write.d.ts +1 -1
- package/dist/scaffold/write.d.ts.map +1 -1
- package/dist/schema/index.js +4 -3
- package/dist/server/deploy-meta.d.ts +25 -0
- package/dist/server/deploy-meta.d.ts.map +1 -0
- package/dist/server/deploy.d.ts +7 -2
- package/dist/server/deploy.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +52 -18
- package/dist/server/realtime.d.ts +4 -1
- package/dist/server/realtime.d.ts.map +1 -1
- package/dist/server/server.d.ts +1 -0
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/sprites.d.ts +18 -1
- package/dist/server/sprites.d.ts.map +1 -1
- package/dist/server/tenancy.d.ts +4 -0
- package/dist/server/tenancy.d.ts.map +1 -1
- package/dist/server/usage-meter.d.ts +53 -0
- package/dist/server/usage-meter.d.ts.map +1 -0
- package/dist/{server-IGBIIJSF.js → server-MB3OPSPI.js} +6 -1
- package/dist/{server-BOH7M4TT.js → server-ZVWGLLRF.js} +7 -2
- package/dist/sprites-KQGTGM6W.js +27 -0
- package/dist/{tenancy-S676GLID.js → tenancy-NBLLGCNJ.js} +1 -1
- package/dist/{tenancy-OP34NFFS.js → tenancy-POMWQP6M.js} +5 -3
- package/dist/vcs/index.js +3 -3
- package/dist/vcs/types.d.ts +2 -0
- package/dist/vcs/types.d.ts.map +1 -1
- package/package.json +17 -6
- package/dist/better-sqlite-backend-PII64VE6.js +0 -159
- package/dist/better-sqlite-backend-VUBVQ7SN.js +0 -209
- package/dist/better-sqlite-backend-Y3AQN65E.js +0 -159
- package/dist/better-sqlite-backend-Y3M7DXOX.js +0 -159
- package/dist/boot-middleware-FJDGVUM4.js +0 -9
- package/dist/boot-middleware-MLJUTLUM.js +0 -9
- package/dist/boot-middleware-ZZPDZNYR.js +0 -9
- package/dist/chunk-276LKLZR.js +0 -359
- package/dist/chunk-2CX5UCRV.js +0 -111
- package/dist/chunk-2ESYSVXG.js +0 -48
- package/dist/chunk-2I5JU73Y.js +0 -340
- package/dist/chunk-2UNSRRNB.js +0 -171
- package/dist/chunk-335UEHQR.js +0 -907
- package/dist/chunk-4CF2L46N.js +0 -29
- package/dist/chunk-5CINODKT.js +0 -41
- package/dist/chunk-5ESGWJ5L.js +0 -45
- package/dist/chunk-5FGLQGMF.js +0 -1676
- package/dist/chunk-5IQZFITY.js +0 -357
- package/dist/chunk-5JWFAQDW.js +0 -150
- package/dist/chunk-62UHTVU3.js +0 -141
- package/dist/chunk-66UJQT2I.js +0 -35
- package/dist/chunk-6RNNVOAS.js +0 -355
- package/dist/chunk-6X23PZ6H.js +0 -969
- package/dist/chunk-7C7LL6MB.js +0 -315
- package/dist/chunk-7F4HM3JG.js +0 -394
- package/dist/chunk-7KJ7T4D3.js +0 -910
- package/dist/chunk-7QQQNUB5.js +0 -92
- package/dist/chunk-7QWJBS72.js +0 -946
- package/dist/chunk-7R36OZK3.js +0 -957
- package/dist/chunk-7UPKCOHE.js +0 -946
- package/dist/chunk-A3BONW34.js +0 -35
- package/dist/chunk-AHMDVHBL.js +0 -141
- package/dist/chunk-AW6A4OZY.js +0 -171
- package/dist/chunk-BJ5EKCJ5.js +0 -458
- package/dist/chunk-BRGYDO7D.js +0 -223
- package/dist/chunk-C5KPSEDN.js +0 -359
- package/dist/chunk-CCTNYTUC.js +0 -940
- package/dist/chunk-CYQ2OVD2.js +0 -35
- package/dist/chunk-DDAK7YOE.js +0 -299
- package/dist/chunk-DRILKBY6.js +0 -965
- package/dist/chunk-DXE24HNN.js +0 -45
- package/dist/chunk-E7ICUNW7.js +0 -945
- package/dist/chunk-EAL2PUOE.js +0 -10022
- package/dist/chunk-ELT7MLZB.js +0 -109
- package/dist/chunk-EWEIRF6G.js +0 -171
- package/dist/chunk-F5VDGQJC.js +0 -120
- package/dist/chunk-FCPL3IEQ.js +0 -98
- package/dist/chunk-FDPKYSV7.js +0 -96
- package/dist/chunk-FES3TC24.js +0 -171
- package/dist/chunk-FOWKR5TW.js +0 -129
- package/dist/chunk-G3XIHPSQ.js +0 -361
- package/dist/chunk-GKJLYLVU.js +0 -359
- package/dist/chunk-GNXHXNVQ.js +0 -113
- package/dist/chunk-GSR6ILTM.js +0 -277
- package/dist/chunk-GWRIMRSX.js +0 -45
- package/dist/chunk-H72UW2HJ.js +0 -45
- package/dist/chunk-HGI74PXB.js +0 -7417
- package/dist/chunk-HGRA37LO.js +0 -145
- package/dist/chunk-HXSRQO3L.js +0 -145
- package/dist/chunk-IG2X2BVO.js +0 -373
- package/dist/chunk-IIJVDD54.js +0 -373
- package/dist/chunk-IX4BBOIT.js +0 -394
- package/dist/chunk-IXU4RMQM.js +0 -349
- package/dist/chunk-J6OUIION.js +0 -857
- package/dist/chunk-K46RNFDE.js +0 -171
- package/dist/chunk-KAGU2XMY.js +0 -359
- package/dist/chunk-KCVYJNVX.js +0 -394
- package/dist/chunk-KYLIQ3YI.js +0 -399
- package/dist/chunk-KZYJJIRN.js +0 -946
- package/dist/chunk-LFOX744K.js +0 -96
- package/dist/chunk-LHOVJEWR.js +0 -7403
- package/dist/chunk-LOPXTPF3.js +0 -120
- package/dist/chunk-LZR3VIFU.js +0 -907
- package/dist/chunk-MCKGQKYU.js +0 -15
- package/dist/chunk-MU6EOS6F.js +0 -0
- package/dist/chunk-MWRQ2TXT.js +0 -357
- package/dist/chunk-NO73OK2I.js +0 -102
- package/dist/chunk-NPE2YJHK.js +0 -394
- package/dist/chunk-NSDXU6QX.js +0 -2213
- package/dist/chunk-NXIRDSZ6.js +0 -145
- package/dist/chunk-NZWFNHCS.js +0 -407
- package/dist/chunk-OB4CMMX6.js +0 -260
- package/dist/chunk-OBKU74FU.js +0 -7411
- package/dist/chunk-OQNDWRDE.js +0 -145
- package/dist/chunk-OVWAJMB6.js +0 -394
- package/dist/chunk-PDHLBTTD.js +0 -45
- package/dist/chunk-PEQNRKLG.js +0 -210
- package/dist/chunk-QERIS7QY.js +0 -7403
- package/dist/chunk-QHA2DM3C.js +0 -373
- package/dist/chunk-QLM4HSYC.js +0 -45
- package/dist/chunk-S2OT3TQJ.js +0 -283
- package/dist/chunk-S5PHSN5K.js +0 -907
- package/dist/chunk-SIAA4J6H.js +0 -21
- package/dist/chunk-SQBNLUIA.js +0 -171
- package/dist/chunk-STLN6A6B.js +0 -355
- package/dist/chunk-U7HV7GU2.js +0 -17
- package/dist/chunk-UGZHOGRA.js +0 -39
- package/dist/chunk-UICF66FS.js +0 -359
- package/dist/chunk-UK3EQREE.js +0 -1078
- package/dist/chunk-UPKPURVY.js +0 -394
- package/dist/chunk-URC74VCN.js +0 -959
- package/dist/chunk-V3G7Q3QQ.js +0 -102
- package/dist/chunk-VUJ6SA55.js +0 -303
- package/dist/chunk-VUJQLIML.js +0 -141
- package/dist/chunk-VWKLKLYB.js +0 -267
- package/dist/chunk-VYC3RZMK.js +0 -277
- package/dist/chunk-WMERMSWI.js +0 -154
- package/dist/chunk-WMR777PO.js +0 -2213
- package/dist/chunk-X46IECAC.js +0 -517
- package/dist/chunk-XEN3OEYY.js +0 -2234
- package/dist/chunk-XZQ66K7A.js +0 -124
- package/dist/chunk-YY3GF7DH.js +0 -7411
- package/dist/chunk-ZE5R3H4C.js +0 -907
- package/dist/chunk-ZMN5LUB7.js +0 -7411
- package/dist/chunk-ZUV4MD5U.js +0 -94
- package/dist/config-KMY6RRK3.js +0 -19
- package/dist/config-VDMK2DUJ.js +0 -19
- package/dist/deploy-SO7AFK6L.js +0 -9
- package/dist/engine-7GXBM4IT.js +0 -7
- package/dist/engine-NSR6BIF7.js +0 -7
- package/dist/factory-2P64OC7M.js +0 -34
- package/dist/factory-YP4ZZK5K.js +0 -34
- package/dist/import-AJLYHFIA.js +0 -10
- package/dist/launch-explorer-AI6L2AWJ.js +0 -91
- package/dist/query-GJL3CVGN.js +0 -31
- package/dist/query-MBJSK3EB.js +0 -31
- package/dist/query-TJHEVSKL.js +0 -31
- package/dist/query-WUIKOHPE.js +0 -524
- package/dist/remote-manager-BLJZ6KF6.js +0 -224
- package/dist/remote-manager-BPYE46SI.js +0 -223
- package/dist/remote-manager-FMESEAFA.js +0 -224
- package/dist/remote-manager-K2WZ5RHY.js +0 -223
- package/dist/remote-manager-SG5PQKCH.js +0 -224
- package/dist/remote-manager-WGP6MIQZ.js +0 -224
- package/dist/sdk-3KBB3E6V.js +0 -16
- package/dist/sdk-4ZQO6UTU.js +0 -16
- package/dist/sdk-6JA6GV3G.js +0 -16
- package/dist/sdk-6VTP5UTZ.js +0 -16
- package/dist/sdk-7VS6TYCD.js +0 -16
- package/dist/sdk-HQ3FTLRT.js +0 -16
- package/dist/sdk-HZ7NU3XE.js +0 -15
- package/dist/sdk-KBQE2OXT.js +0 -16
- package/dist/sdk-MSCDZ7JU.js +0 -15
- package/dist/sdk-WNZOGO3S.js +0 -15
- package/dist/sdk-YLV33ZCW.js +0 -9
- package/dist/sdk-ZSUD2LLJ.js +0 -16
- package/dist/server-AFXFFBWA.js +0 -11
- package/dist/server-AGHC4VUL.js +0 -11
- package/dist/server-DBUY2KY5.js +0 -11
- package/dist/server-GWBQJPRG.js +0 -11
- package/dist/server-JZZFULVU.js +0 -11
- package/dist/server-L5XAF4M5.js +0 -11
- package/dist/server-NYFUHANA.js +0 -12
- package/dist/server-OABUB2LO.js +0 -12
- package/dist/server-P2CKZWWV.js +0 -12
- package/dist/sprites-XVSMQLSI.js +0 -15
- package/dist/sql-wasm-FORCZFHZ.js +0 -2148
- package/dist/sql-wasm-JZH76RLO.js +0 -2148
- package/dist/sqljs-backend-CJQOIQYE.js +0 -266
- package/dist/sqljs-backend-KWXBUDUO.js +0 -266
- package/dist/state-demo.bundle.js +0 -1033
- package/dist/tenancy-CBWYEVUB.js +0 -11
- package/dist/tenancy-FO6WVYFN.js +0 -13
- package/dist/tenancy-FWDBESMX.js +0 -14
- package/dist/tenancy-HGPIS5QA.js +0 -13
- package/dist/tenancy-HXFALA37.js +0 -14
- package/dist/tenancy-V7ARWNNV.js +0 -14
- package/dist/tenancy-ZDN4GXK5.js +0 -13
- package/dist/tenancy-ZT5VMY7B.js +0 -14
- package/dist/vm-config-YZRJ3KUB.js +0 -21
- /package/dist/{chunk-2BRTCEHB.js → chunk-PZ4XYZ4J.js} +0 -0
- /package/dist/{chunk-EO3J7GRP.js → chunk-WXSWA3MV.js} +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
// src/client/sdk.browser.ts
|
|
2
|
+
function isRemote(opts) {
|
|
3
|
+
return "url" in opts;
|
|
4
|
+
}
|
|
5
|
+
function browserOnlyRemoteError(feature) {
|
|
6
|
+
return new Error(
|
|
7
|
+
`${feature} is not available in browser bundles. Use remote mode with \`new TrellisDb({ url })\`, or import \`trellis/client\` in Node.`
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
var TrellisDb = class {
|
|
11
|
+
opts;
|
|
12
|
+
_ws = null;
|
|
13
|
+
/** In-flight connect — concurrent subscribe() shares one socket open. */
|
|
14
|
+
_wsPromise = null;
|
|
15
|
+
_subCallbacks = /* @__PURE__ */ new Map();
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
if (!isRemote(opts)) {
|
|
18
|
+
throw browserOnlyRemoteError("TrellisDb local mode");
|
|
19
|
+
}
|
|
20
|
+
this.opts = opts;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Browser bundles cannot read `.trellis-db.json`.
|
|
24
|
+
*/
|
|
25
|
+
static async fromConfig(_dir = ".") {
|
|
26
|
+
throw browserOnlyRemoteError("TrellisDb.fromConfig()");
|
|
27
|
+
}
|
|
28
|
+
// -------------------------------------------------------------------------
|
|
29
|
+
// CRUD
|
|
30
|
+
// -------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Create a new entity.
|
|
33
|
+
* Returns the generated entity ID.
|
|
34
|
+
*/
|
|
35
|
+
async create(type, attributes = {}, links) {
|
|
36
|
+
const res = await this._fetch("POST", "/entities", {
|
|
37
|
+
type,
|
|
38
|
+
attributes,
|
|
39
|
+
links
|
|
40
|
+
});
|
|
41
|
+
return res.id;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Read an entity by ID.
|
|
45
|
+
* Returns null if not found.
|
|
46
|
+
*/
|
|
47
|
+
async read(id) {
|
|
48
|
+
try {
|
|
49
|
+
return await this._fetch(
|
|
50
|
+
"GET",
|
|
51
|
+
`/entities/${encodeURIComponent(id)}`
|
|
52
|
+
);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
if (err?.status === 404) return null;
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Update an entity's attributes (partial update).
|
|
60
|
+
*/
|
|
61
|
+
async update(id, attributes) {
|
|
62
|
+
await this._fetch(
|
|
63
|
+
"PUT",
|
|
64
|
+
`/entities/${encodeURIComponent(id)}`,
|
|
65
|
+
attributes
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Delete an entity by ID.
|
|
70
|
+
*/
|
|
71
|
+
async delete(id) {
|
|
72
|
+
await this._fetch("DELETE", `/entities/${encodeURIComponent(id)}`);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* List entities of a given type.
|
|
76
|
+
*/
|
|
77
|
+
async list(type, opts = {}) {
|
|
78
|
+
const params = new URLSearchParams();
|
|
79
|
+
if (type) params.set("type", type);
|
|
80
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
81
|
+
if (opts.offset) params.set("offset", String(opts.offset));
|
|
82
|
+
const qs = params.toString() ? `?${params}` : "";
|
|
83
|
+
return await this._fetch("GET", `/entities${qs}`);
|
|
84
|
+
}
|
|
85
|
+
// -------------------------------------------------------------------------
|
|
86
|
+
// Query
|
|
87
|
+
// -------------------------------------------------------------------------
|
|
88
|
+
/**
|
|
89
|
+
* Run an EQL-S query string.
|
|
90
|
+
*/
|
|
91
|
+
async query(eql) {
|
|
92
|
+
return await this._fetch("POST", "/query", {
|
|
93
|
+
query: eql
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// -------------------------------------------------------------------------
|
|
97
|
+
// Schema registration
|
|
98
|
+
// -------------------------------------------------------------------------
|
|
99
|
+
/**
|
|
100
|
+
* Register a user/system-tier ontology schema with a remote Trellis server.
|
|
101
|
+
*/
|
|
102
|
+
async registerType(schema) {
|
|
103
|
+
const def = "@id" in schema ? schema : schema.definition;
|
|
104
|
+
try {
|
|
105
|
+
await this._fetch("POST", "/ontologies", def);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (err instanceof FetchError && err.status === 409) return;
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// -------------------------------------------------------------------------
|
|
112
|
+
// File upload
|
|
113
|
+
// -------------------------------------------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Upload a file to the blob store.
|
|
116
|
+
* Returns a content-addressed hash.
|
|
117
|
+
*/
|
|
118
|
+
async upload(data, contentType = "application/octet-stream") {
|
|
119
|
+
const raw = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
|
|
120
|
+
const cleanBuf = raw.buffer.slice(
|
|
121
|
+
raw.byteOffset,
|
|
122
|
+
raw.byteOffset + raw.byteLength
|
|
123
|
+
);
|
|
124
|
+
const res = await fetch(`${this.opts.url}/upload`, {
|
|
125
|
+
method: "POST",
|
|
126
|
+
headers: {
|
|
127
|
+
"Content-Type": contentType,
|
|
128
|
+
...this.opts.apiKey ? { Authorization: `Bearer ${this.opts.apiKey}` } : {}
|
|
129
|
+
},
|
|
130
|
+
body: cleanBuf
|
|
131
|
+
});
|
|
132
|
+
if (!res.ok) throw new FetchError(res.status, await res.text());
|
|
133
|
+
return await res.json();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Download a file by its blob hash.
|
|
137
|
+
*/
|
|
138
|
+
async getFile(hash) {
|
|
139
|
+
const res = await fetch(
|
|
140
|
+
`${this.opts.url}/files/${encodeURIComponent(hash)}`,
|
|
141
|
+
{
|
|
142
|
+
headers: this.opts.apiKey ? { Authorization: `Bearer ${this.opts.apiKey}` } : {}
|
|
143
|
+
}
|
|
144
|
+
);
|
|
145
|
+
if (res.status === 404) return null;
|
|
146
|
+
if (!res.ok) throw new FetchError(res.status, await res.text());
|
|
147
|
+
return new Uint8Array(await res.arrayBuffer());
|
|
148
|
+
}
|
|
149
|
+
// -------------------------------------------------------------------------
|
|
150
|
+
// Auth helpers
|
|
151
|
+
// -------------------------------------------------------------------------
|
|
152
|
+
async register(email, password, name) {
|
|
153
|
+
return await this._fetch("POST", "/auth/register", {
|
|
154
|
+
email,
|
|
155
|
+
password,
|
|
156
|
+
name
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async login(email, password) {
|
|
160
|
+
return await this._fetch("POST", "/auth/login", {
|
|
161
|
+
email,
|
|
162
|
+
password
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Set the active API key / JWT token for subsequent requests.
|
|
167
|
+
*/
|
|
168
|
+
setToken(token) {
|
|
169
|
+
this.opts.apiKey = token;
|
|
170
|
+
}
|
|
171
|
+
// -------------------------------------------------------------------------
|
|
172
|
+
// Realtime
|
|
173
|
+
// -------------------------------------------------------------------------
|
|
174
|
+
/**
|
|
175
|
+
* Subscribe to a live EQL-S query.
|
|
176
|
+
* Callback is fired immediately with the initial result, then on every update.
|
|
177
|
+
*/
|
|
178
|
+
subscribe(eql, callback, opts) {
|
|
179
|
+
const subId = `sub_${crypto.randomUUID()}`;
|
|
180
|
+
this._subCallbacks.set(subId, callback);
|
|
181
|
+
this._ensureWs().then((ws) => {
|
|
182
|
+
ws.send(
|
|
183
|
+
JSON.stringify({
|
|
184
|
+
type: "subscribe",
|
|
185
|
+
id: subId,
|
|
186
|
+
query: eql,
|
|
187
|
+
...opts?.entityType ? { entityType: opts.entityType } : {},
|
|
188
|
+
...opts?.resolve ? { resolve: opts.resolve } : {}
|
|
189
|
+
})
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
return {
|
|
193
|
+
unsubscribe: () => {
|
|
194
|
+
this._subCallbacks.delete(subId);
|
|
195
|
+
this._ws?.send(JSON.stringify({ type: "unsubscribe", id: subId }));
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Close the WebSocket connection.
|
|
201
|
+
*/
|
|
202
|
+
disconnect() {
|
|
203
|
+
const ws = this._ws;
|
|
204
|
+
this._ws = null;
|
|
205
|
+
this._wsPromise = null;
|
|
206
|
+
ws?.close();
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Close open client resources.
|
|
210
|
+
*/
|
|
211
|
+
close() {
|
|
212
|
+
this.disconnect();
|
|
213
|
+
}
|
|
214
|
+
// -------------------------------------------------------------------------
|
|
215
|
+
// Private
|
|
216
|
+
// -------------------------------------------------------------------------
|
|
217
|
+
async _fetch(method, path, body) {
|
|
218
|
+
const url = `${this.opts.url}${path}`;
|
|
219
|
+
const res = await fetch(url, {
|
|
220
|
+
method,
|
|
221
|
+
headers: {
|
|
222
|
+
"Content-Type": "application/json",
|
|
223
|
+
...this.opts.apiKey ? { Authorization: `Bearer ${this.opts.apiKey}` } : {}
|
|
224
|
+
},
|
|
225
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
226
|
+
});
|
|
227
|
+
const data = await res.json();
|
|
228
|
+
if (!res.ok)
|
|
229
|
+
throw new FetchError(
|
|
230
|
+
res.status,
|
|
231
|
+
data?.message ?? res.statusText,
|
|
232
|
+
data
|
|
233
|
+
);
|
|
234
|
+
return data;
|
|
235
|
+
}
|
|
236
|
+
_ensureWs() {
|
|
237
|
+
if (this._ws?.readyState === WebSocket.OPEN) {
|
|
238
|
+
return Promise.resolve(this._ws);
|
|
239
|
+
}
|
|
240
|
+
if (this._wsPromise) {
|
|
241
|
+
return this._wsPromise;
|
|
242
|
+
}
|
|
243
|
+
const wsUrl = this.opts.url.replace(
|
|
244
|
+
/^https?/,
|
|
245
|
+
this.opts.url.startsWith("https") ? "wss" : "ws"
|
|
246
|
+
) + "/realtime";
|
|
247
|
+
this._wsPromise = new Promise((resolve, reject) => {
|
|
248
|
+
const ws = new WebSocket(wsUrl);
|
|
249
|
+
ws.onopen = () => {
|
|
250
|
+
this._ws = ws;
|
|
251
|
+
resolve(ws);
|
|
252
|
+
};
|
|
253
|
+
ws.onerror = (e) => {
|
|
254
|
+
reject(e instanceof Error ? e : new Error("WebSocket error"));
|
|
255
|
+
};
|
|
256
|
+
ws.onmessage = (e) => {
|
|
257
|
+
try {
|
|
258
|
+
const msg = JSON.parse(e.data);
|
|
259
|
+
if (msg.type === "data" && this._subCallbacks.has(msg.id)) {
|
|
260
|
+
const meta = msg.resolved === true ? { resolved: true } : void 0;
|
|
261
|
+
this._subCallbacks.get(msg.id)(msg.result, msg.diff, meta);
|
|
262
|
+
}
|
|
263
|
+
} catch {
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
ws.onclose = () => {
|
|
267
|
+
if (this._ws === ws) {
|
|
268
|
+
this._ws = null;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
}).finally(() => {
|
|
272
|
+
this._wsPromise = null;
|
|
273
|
+
});
|
|
274
|
+
return this._wsPromise;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
var FetchError = class extends Error {
|
|
278
|
+
constructor(status, message, body) {
|
|
279
|
+
super(`HTTP ${status}: ${message}`);
|
|
280
|
+
this.status = status;
|
|
281
|
+
this.body = body;
|
|
282
|
+
this.name = "FetchError";
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
export {
|
|
287
|
+
TrellisDb,
|
|
288
|
+
FetchError
|
|
289
|
+
};
|
|
@@ -13,6 +13,12 @@ import { existsSync, mkdirSync } from "fs";
|
|
|
13
13
|
import { join, resolve } from "path";
|
|
14
14
|
var DEFAULT_TENANT = "default";
|
|
15
15
|
var TENANTS_DIR = "tenants";
|
|
16
|
+
function resolvePoolBackendFromEnv() {
|
|
17
|
+
const backend = process.env.TRELLIS_BACKEND;
|
|
18
|
+
if (backend === "sqljs") return { backend: "sqljs" };
|
|
19
|
+
if (backend === "better-sqlite") return { backend: "better-sqlite" };
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
16
22
|
var TenantPool = class {
|
|
17
23
|
pool = /* @__PURE__ */ new Map();
|
|
18
24
|
dbPath;
|
|
@@ -43,6 +49,12 @@ var TenantPool = class {
|
|
|
43
49
|
get(tenantId) {
|
|
44
50
|
const id = tenantId ?? DEFAULT_TENANT;
|
|
45
51
|
if (!this.pool.has(id)) {
|
|
52
|
+
const isBun = typeof process !== "undefined" && Boolean(process.versions?.bun);
|
|
53
|
+
if (!isBun) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
"TenantPool.get() on Node requires `await pool.preload()` first. `trellis db serve` preloads automatically; custom servers should call preload before get()."
|
|
56
|
+
);
|
|
57
|
+
}
|
|
46
58
|
this.pool.set(id, this._createKernelSync(id));
|
|
47
59
|
}
|
|
48
60
|
return this.pool.get(id);
|
|
@@ -94,6 +106,10 @@ var TenantPool = class {
|
|
|
94
106
|
}
|
|
95
107
|
this.pool.clear();
|
|
96
108
|
}
|
|
109
|
+
/** Absolute path to the tenant data directory. */
|
|
110
|
+
dataPath() {
|
|
111
|
+
return this.dbPath;
|
|
112
|
+
}
|
|
97
113
|
/**
|
|
98
114
|
* Return the SQLite file path for a given tenant.
|
|
99
115
|
*/
|
|
@@ -141,5 +157,6 @@ var TenantPool = class {
|
|
|
141
157
|
|
|
142
158
|
export {
|
|
143
159
|
DEFAULT_TENANT,
|
|
160
|
+
resolvePoolBackendFromEnv,
|
|
144
161
|
TenantPool
|
|
145
162
|
};
|
|
@@ -330,7 +330,7 @@ var TrellisDb = class _TrellisDb {
|
|
|
330
330
|
async _getPool() {
|
|
331
331
|
if (this._pool) return this._pool;
|
|
332
332
|
if (!this._poolPromise) {
|
|
333
|
-
this._poolPromise = import("./tenancy-
|
|
333
|
+
this._poolPromise = import("./tenancy-NBLLGCNJ.js").then(({ TenantPool }) => {
|
|
334
334
|
const path = this.opts.path;
|
|
335
335
|
this._pool = new TenantPool(path);
|
|
336
336
|
return this._pool;
|