@midsummer-ai/sdk 0.1.0-next.1305 → 0.1.0-next.900
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/{connection-CxD_Nry5.mjs → connection-CDk7H1FL.mjs} +6 -46
- package/database/client.mjs +9 -16
- package/database/stand-in.d.mts +2 -5
- package/database/stand-in.mjs +5 -13
- package/package.json +1 -1
- package/{store-DDuOr-_F.mjs → store-BzI9at5x.mjs} +1 -1
- package/{tabs-4FLTfg1c.mjs → tabs-D-P8_ci_.mjs} +1 -1
|
@@ -263,46 +263,6 @@ const SHARED = /* @__PURE__ */ new Map();
|
|
|
263
263
|
* window is admitted to the main LRU only if a count-min sketch (4 rows of 4-bit-ish counters, halved every 10x the
|
|
264
264
|
* size in accesses) says it is used more often than the main LRU's victim. `touch` every access (hit or miss), `add`
|
|
265
265
|
* a missed key: it returns the keys that left the cache (possibly the one leaving the window). */
|
|
266
|
-
/**
|
|
267
|
-
* Where a request to `url` goes, and the headers that name it. A `*.localhost` name is loopback (RFC 6761)
|
|
268
|
-
* whatever the system's resolver says, and a Debian container's says nothing: outside a browser, which
|
|
269
|
-
* resolves it itself and never lets a page set Host, it goes to 127.0.0.1 with the name as its Host
|
|
270
|
-
* (and, over TLS, as the name the certificate is checked for). Anything else goes as it is.
|
|
271
|
-
* const { url, init } = loopback("http://db-a.localhost:8792/ws"); fetch(url, init)
|
|
272
|
-
*/
|
|
273
|
-
function loopback(url, g = globalThis) {
|
|
274
|
-
const at = new URL(url);
|
|
275
|
-
if (g.document !== void 0 || !at.hostname.endsWith(".localhost")) return {
|
|
276
|
-
url: String(url),
|
|
277
|
-
init: {}
|
|
278
|
-
};
|
|
279
|
-
const host = at.host, name = at.hostname;
|
|
280
|
-
at.hostname = "127.0.0.1";
|
|
281
|
-
return {
|
|
282
|
-
url: at.href,
|
|
283
|
-
init: {
|
|
284
|
-
headers: { Host: host },
|
|
285
|
-
.../^(https|wss):$/u.test(at.protocol) ? { tls: { serverName: name } } : {}
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
/** `fetch` of `url` through `loopback`, `init`'s headers kept beside its Host. */
|
|
290
|
-
const fetchAt = (url, init = {}) => {
|
|
291
|
-
const to = loopback(url);
|
|
292
|
-
return to.init.headers ? fetch(to.url, {
|
|
293
|
-
...init,
|
|
294
|
-
...to.init,
|
|
295
|
-
headers: {
|
|
296
|
-
...Object.fromEntries(new Headers(init.headers ?? {})),
|
|
297
|
-
...to.init.headers
|
|
298
|
-
}
|
|
299
|
-
}) : fetch(to.url, init);
|
|
300
|
-
};
|
|
301
|
-
/** A WebSocket to `url` through `loopback`. */
|
|
302
|
-
const socketAt = (url) => {
|
|
303
|
-
const to = loopback(url);
|
|
304
|
-
return to.init.headers ? new WebSocket(to.url, to.init) : new WebSocket(to.url);
|
|
305
|
-
};
|
|
306
266
|
var TinyLfu = class {
|
|
307
267
|
constructor(size, { windowShare = .01 } = {}) {
|
|
308
268
|
this.size = Math.max(2, Math.floor(size));
|
|
@@ -403,8 +363,8 @@ var Connection = class Connection {
|
|
|
403
363
|
...options,
|
|
404
364
|
shape
|
|
405
365
|
};
|
|
406
|
-
if (o.store === void 0 && typeof indexedDB !== "undefined" && typeof document !== "undefined") o.store = (await import("./store-
|
|
407
|
-
if (o.tabs !== false && typeof document !== "undefined") return (await import("./tabs-
|
|
366
|
+
if (o.store === void 0 && typeof indexedDB !== "undefined" && typeof document !== "undefined") o.store = (await import("./store-BzI9at5x.mjs")).idbStore(new URL(url).host);
|
|
367
|
+
if (o.tabs !== false && typeof document !== "undefined") return (await import("./tabs-D-P8_ci_.mjs")).ConnectionTabs.connect(url, o);
|
|
408
368
|
return Connection.open(url, o);
|
|
409
369
|
}
|
|
410
370
|
/** A Connection over one socket, of the shape given (default "browser"), no detection (tabs.mjs opens its own so). */
|
|
@@ -557,7 +517,7 @@ var Connection = class Connection {
|
|
|
557
517
|
const exp = expOf(this.token);
|
|
558
518
|
if (!this.token || exp && exp * 1e3 - Date.now() < 6e4) return true;
|
|
559
519
|
try {
|
|
560
|
-
return (await
|
|
520
|
+
return (await fetch(this.url.replace(/^ws/u, "http"), { signal: AbortSignal.timeout(1e4) })).status === 401;
|
|
561
521
|
} catch {
|
|
562
522
|
return false;
|
|
563
523
|
}
|
|
@@ -583,7 +543,7 @@ var Connection = class Connection {
|
|
|
583
543
|
openOnce() {
|
|
584
544
|
return new Promise((ready, fail) => {
|
|
585
545
|
const dialed = this.dial ? Promise.resolve(this.dial(this)) : null;
|
|
586
|
-
const ws = dialed ? null :
|
|
546
|
+
const ws = dialed ? null : new WebSocket(this.url);
|
|
587
547
|
const timer = setTimeout(() => {
|
|
588
548
|
fail(/* @__PURE__ */ new Error("open timeout"));
|
|
589
549
|
try {
|
|
@@ -1525,7 +1485,7 @@ var Connection = class Connection {
|
|
|
1525
1485
|
}
|
|
1526
1486
|
/** Stores a file (R2) and its `_files` row (owner: this user); resolves its id. */
|
|
1527
1487
|
async upload(blob, name) {
|
|
1528
|
-
const put = () =>
|
|
1488
|
+
const put = () => fetch(`${this.base}/files?${this.auth()}&name=${encodeURIComponent(name)}`, {
|
|
1529
1489
|
method: "PUT",
|
|
1530
1490
|
body: blob
|
|
1531
1491
|
});
|
|
@@ -1820,7 +1780,7 @@ var Connection = class Connection {
|
|
|
1820
1780
|
}
|
|
1821
1781
|
const home = this.homes.get(hk);
|
|
1822
1782
|
if (!home) return null;
|
|
1823
|
-
const ws =
|
|
1783
|
+
const ws = new WebSocket(`${this.base.replace(/^http/u, "ws")}/ws?token=${encodeURIComponent(this.token)}&home=${encodeURIComponent(home)}`);
|
|
1824
1784
|
lane = {
|
|
1825
1785
|
unit,
|
|
1826
1786
|
ws,
|
package/database/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DatabaseError } from "./errors.mjs";
|
|
2
|
-
import { t as Connection } from "../connection-
|
|
2
|
+
import { t as Connection } from "../connection-CDk7H1FL.mjs";
|
|
3
3
|
//#region src/database/client.ts
|
|
4
4
|
/**
|
|
5
5
|
* `@midsummer-ai/sdk/database`: a Project's Database, from its app or its server.
|
|
@@ -11,16 +11,16 @@ import { t as Connection } from "../connection-CxD_Nry5.mjs";
|
|
|
11
11
|
* const id = await db.mutation(api.messages.send, { channel: "general", body: "hi" })
|
|
12
12
|
* const stop = db.watch(api.messages.list, { channel: "general" }, (messages) => render(messages))
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* proves it; in a CI run or an Agent's run, where the run's Workload token does; and under
|
|
17
|
-
* `midsummer dev`, where every binding reaches the Database's Stand-in.
|
|
14
|
+
* In your Deployment's server, Midsummer hands in the Databases the Environment binds as
|
|
15
|
+
* `context.database`: name one by its binding name, and no key is kept anywhere.
|
|
18
16
|
*
|
|
19
|
-
* const db = await connect({ binding: "main" })
|
|
17
|
+
* const db = await connect({ database: context.database, binding: "main" })
|
|
20
18
|
*
|
|
21
|
-
*
|
|
19
|
+
* In a CI run or an Agent's run, the run's Environment binds it the same way, and the run's own
|
|
20
|
+
* Workload token is what proves it: no key there either. Under `midsummer dev`, every binding
|
|
21
|
+
* reaches the Database's Stand-in.
|
|
22
22
|
*
|
|
23
|
-
* const db = await connect({
|
|
23
|
+
* const db = await connect({ binding: "main" })
|
|
24
24
|
*
|
|
25
25
|
* From code outside Midsummer, a Database Key is enough: it is exchanged for a token, and again
|
|
26
26
|
* before that token runs out.
|
|
@@ -61,14 +61,7 @@ async function connect(options) {
|
|
|
61
61
|
refresh = async () => (await options.database.token(options.binding)).token;
|
|
62
62
|
} else if ("binding" in options) {
|
|
63
63
|
const env = globalThis.process?.env ?? {};
|
|
64
|
-
|
|
65
|
-
const bound = here?.()?.database;
|
|
66
|
-
if (bound) {
|
|
67
|
-
const first = await bound.token(options.binding);
|
|
68
|
-
url = first.url;
|
|
69
|
-
token = first.token;
|
|
70
|
-
refresh = async () => (await bound.token(options.binding)).token;
|
|
71
|
-
} else if (env.MIDSUMMER_DATABASE_URL) {
|
|
64
|
+
if (env.MIDSUMMER_DATABASE_URL) {
|
|
72
65
|
url = env.MIDSUMMER_DATABASE_URL;
|
|
73
66
|
token = env.MIDSUMMER_DATABASE_TOKEN;
|
|
74
67
|
} else {
|
package/database/stand-in.d.mts
CHANGED
|
@@ -55,11 +55,8 @@ interface StandIn {
|
|
|
55
55
|
close(): void;
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
-
* Writes a build's files under `folder` and loads them, each import of the surface naming this SDK
|
|
59
|
-
*
|
|
60
|
-
* module loaded here: a file on disk can't import one inside a compiled CLI, where this SDK's files
|
|
61
|
-
* live only in the binary. Each load is a folder of its own, so a module loaded before never stands in
|
|
62
|
-
* for a newer one.
|
|
58
|
+
* Writes a build's files under `folder` and loads them, each import of the surface naming this SDK.
|
|
59
|
+
* Each load is a folder of its own, so a module loaded before never stands in for a newer one.
|
|
63
60
|
*/
|
|
64
61
|
declare function loadDatabase(built: Built, folder: string): Promise<Loaded>;
|
|
65
62
|
/** A row as the Stand-in keeps it: its fields and its version, which counts its writes. */
|
package/database/stand-in.mjs
CHANGED
|
@@ -21,26 +21,18 @@ import { pathToFileURL } from "node:url";
|
|
|
21
21
|
* The Project's code runs in this process, as it does on its author's machine. Crons do not run
|
|
22
22
|
* here yet.
|
|
23
23
|
*/
|
|
24
|
-
const SURFACE = /(\bfrom\s*)(["'])(@midsummer
|
|
25
|
-
/** Where the loaded surface waits for the shim each load imports it through. */
|
|
26
|
-
const HELD = Symbol.for("midsummer.database.surface");
|
|
24
|
+
const SURFACE = /(\bfrom\s*)(["'])(@midsummer\/sdk\/server|\.\/_generated\/server(?:\.m?js)?)\2/gu;
|
|
27
25
|
let loads = 0;
|
|
28
26
|
/**
|
|
29
|
-
* Writes a build's files under `folder` and loads them, each import of the surface naming this SDK
|
|
30
|
-
*
|
|
31
|
-
* module loaded here: a file on disk can't import one inside a compiled CLI, where this SDK's files
|
|
32
|
-
* live only in the binary. Each load is a folder of its own, so a module loaded before never stands in
|
|
33
|
-
* for a newer one.
|
|
27
|
+
* Writes a build's files under `folder` and loads them, each import of the surface naming this SDK.
|
|
28
|
+
* Each load is a folder of its own, so a module loaded before never stands in for a newer one.
|
|
34
29
|
*/
|
|
35
30
|
async function loadDatabase(built, folder) {
|
|
36
|
-
const
|
|
37
|
-
globalThis[HELD] = surface;
|
|
38
|
-
const names = Object.keys(surface).filter((name) => name !== "default" && /^[A-Za-z_$][\w$]*$/.test(name));
|
|
31
|
+
const server = new URL("./server.ts", import.meta.url).href;
|
|
39
32
|
const dir = join(folder, `load-${process.pid}-${loads += 1}`);
|
|
40
33
|
await mkdir(join(dir, "_generated"), { recursive: true });
|
|
41
34
|
await writeFile(join(dir, "_generated", "api.mjs"), built.generated["api.mjs"]);
|
|
42
|
-
await writeFile(join(dir,
|
|
43
|
-
for (const [name, text] of Object.entries(built.files)) await writeFile(join(dir, name), text.replace(SURFACE, (_all, from, quote) => `${from}${quote}./_generated/server.mjs${quote}`));
|
|
35
|
+
for (const [name, text] of Object.entries(built.files)) await writeFile(join(dir, name), text.replace(SURFACE, (_all, from, quote) => `${from}${quote}${server}${quote}`));
|
|
44
36
|
const functions = /* @__PURE__ */ new Map();
|
|
45
37
|
for (const fn of built.functions) {
|
|
46
38
|
const exported = (await import(pathToFileURL(join(dir, fn.file)).href))[fn.export];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midsummer-ai/sdk",
|
|
3
|
-
"version": "0.1.0-next.
|
|
3
|
+
"version": "0.1.0-next.900",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Midsummer's handles for an app's code: its Database, Storage, Queues, Vector DB, AI, Email and Agents, with stand-ins for tests.",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Connection } from "./connection-
|
|
1
|
+
import { t as Connection } from "./connection-CDk7H1FL.mjs";
|
|
2
2
|
//#region src/database/client/tabs.mjs
|
|
3
3
|
/** Argument index of the options that take a `tag` (a tab tags its own writes: the same tag after a handover). */
|
|
4
4
|
const TAGGED = {
|