@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.
@@ -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-DDuOr-_F.mjs")).idbStore(new URL(url).host);
407
- if (o.tabs !== false && typeof document !== "undefined") return (await import("./tabs-4FLTfg1c.mjs")).ConnectionTabs.connect(url, o);
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 fetchAt(this.url.replace(/^ws/u, "http"), { signal: AbortSignal.timeout(1e4) })).status === 401;
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 : socketAt(this.url);
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 = () => fetchAt(`${this.base}/files?${this.auth()}&name=${encodeURIComponent(name)}`, {
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 = socketAt(`${this.base.replace(/^http/u, "ws")}/ws?token=${encodeURIComponent(this.token)}&home=${encodeURIComponent(home)}`);
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,
@@ -1,5 +1,5 @@
1
1
  import { DatabaseError } from "./errors.mjs";
2
- import { t as Connection } from "../connection-CxD_Nry5.mjs";
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
- * Name a Database by the name its Environment binds it under, and no key is kept anywhere. The same
15
- * call works in a Deployment's server, whatever framework serves it, where the request's own handle
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
- * A server on Midsummer's own contract is also handed the handle as `context.database`:
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({ database: context.database, binding: "main" })
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
- const here = globalThis[Symbol.for("midsummer.context")];
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 {
@@ -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's
59
- * `server.ts`. They reach it through a shim beside them, `_generated/server.mjs`, that re-exports the
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. */
@@ -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(?:-ai)?\/sdk\/server|\.\/_generated\/server(?:\.m?js)?)\2/gu;
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's
30
- * `server.ts`. They reach it through a shim beside them, `_generated/server.mjs`, that re-exports the
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 surface = await import("./server.mjs");
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, "_generated", "server.mjs"), `const surface = globalThis[Symbol.for("midsummer.database.surface")];\nexport const { ${names.join(", ")} } = surface;\n`);
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.1305",
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 "./connection-CxD_Nry5.mjs";
1
+ import "./connection-CDk7H1FL.mjs";
2
2
  //#region src/database/client/store.mjs
3
3
  const STORES = [
4
4
  "ops",
@@ -1,4 +1,4 @@
1
- import { t as Connection } from "./connection-CxD_Nry5.mjs";
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 = {