@lantharos/pult 0.8.0 → 0.9.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.
@@ -6,6 +6,9 @@ const DEFAULT_STATES = [
6
6
  "in progress",
7
7
  "handled"
8
8
  ];
9
+ function actionId(resource, action) {
10
+ return `${resource}.${action}`;
11
+ }
9
12
  function splitAction(id) {
10
13
  const dot = id.indexOf(".");
11
14
  return dot === -1 ? {
@@ -40,6 +43,17 @@ function mapBlocks(blocks, map) {
40
43
  }];
41
44
  });
42
45
  }
46
+ function valuesIn(block) {
47
+ switch (block.type) {
48
+ case "fields": return block.fields.map((field) => field.value);
49
+ case "stats": return block.stats.map((stat) => stat.value);
50
+ case "table": return block.rows.flat();
51
+ default: return [];
52
+ }
53
+ }
54
+ function shownValue(value) {
55
+ return value && typeof value === "object" && "edit" in value ? value.edit.value : value;
56
+ }
43
57
  //#endregion
44
58
  //#region ../protocol/src/signing.ts
45
59
  const SIGNATURE_TOLERANCE_MS = 3e5;
@@ -112,15 +126,14 @@ var NonceWindow = class {
112
126
  this.ttl = ttl;
113
127
  }
114
128
  claim(nonce, now = Date.now()) {
115
- if (this.#seen.size > 1e4) this.#sweep(now);
116
- const seenAt = this.#seen.get(nonce);
117
- if (seenAt !== void 0 && now - seenAt < this.ttl) return false;
129
+ for (const [seen, at] of this.#seen) {
130
+ if (now - at < this.ttl) break;
131
+ this.#seen.delete(seen);
132
+ }
133
+ if (this.#seen.has(nonce)) return false;
118
134
  this.#seen.set(nonce, now);
119
135
  return true;
120
136
  }
121
- #sweep(now) {
122
- for (const [nonce, at] of this.#seen) if (now - at >= this.ttl) this.#seen.delete(nonce);
123
- }
124
137
  };
125
138
  //#endregion
126
139
  //#region ../protocol/src/wire.ts
@@ -134,15 +147,26 @@ const HEADER = {
134
147
  signature: "pult-signature"
135
148
  };
136
149
  //#endregion
137
- //#region src/define/source.ts
150
+ //#region src/define/core.ts
138
151
  const KIND = Symbol.for("pult.kind");
152
+ const TRACING = Symbol.for("pult.tracing");
139
153
  const FRAME = /\(?((?:file:\/\/)?[^()\s]+?):(\d+):\d+\)?\s*$/;
140
154
  const RUNTIME = /^node:|[\\/]jiti[\\/]/;
141
155
  const UNKNOWN = {
142
156
  file: "",
143
157
  line: 0
144
158
  };
159
+ const flags = globalThis;
160
+ async function traceOrigins(work) {
161
+ flags[TRACING] = true;
162
+ try {
163
+ return await work();
164
+ } finally {
165
+ flags[TRACING] = false;
166
+ }
167
+ }
145
168
  function captureOrigin() {
169
+ if (!flags[TRACING]) return UNKNOWN;
146
170
  const [own, ...callers] = ((/* @__PURE__ */ new Error()).stack?.split("\n").slice(1) ?? []).flatMap(parseFrame);
147
171
  if (!own) return UNKNOWN;
148
172
  const sdk = own.file.replace(/[^\\/]*$/, "");
@@ -158,8 +182,12 @@ function parseFrame(frame) {
158
182
  function kindOf(value) {
159
183
  return value && typeof value === "object" && KIND in value ? value[KIND] : null;
160
184
  }
185
+ function humanize(name) {
186
+ const spaced = name.replace(/[-_]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2");
187
+ return spaced.charAt(0).toUpperCase() + spaced.slice(1);
188
+ }
161
189
  //#endregion
162
- //#region src/define/page.ts
190
+ //#region src/define/inbox/view.ts
163
191
  function view(name, options) {
164
192
  return {
165
193
  [KIND]: "view",
@@ -168,26 +196,6 @@ function view(name, options) {
168
196
  options
169
197
  };
170
198
  }
171
- function page(name, options) {
172
- return {
173
- [KIND]: "page",
174
- origin: captureOrigin(),
175
- name,
176
- options
177
- };
178
- }
179
- function home(options) {
180
- const resolved = Array.isArray(options) || typeof options === "function" ? { render: options } : options;
181
- return {
182
- [KIND]: "page",
183
- origin: captureOrigin(),
184
- name: HOME,
185
- options: {
186
- label: "Home",
187
- ...resolved
188
- }
189
- };
190
- }
191
199
  function normalizeFilter(filter = {}) {
192
200
  const { state, ...rest } = filter;
193
201
  return {
@@ -254,7 +262,7 @@ function listing(target, filter) {
254
262
  }),
255
263
  sort: view.options.sort ?? "-lastSeen",
256
264
  view: view.name,
257
- label: view.options.label ?? view.name
265
+ label: view.options.label ?? humanize(view.name)
258
266
  };
259
267
  }
260
268
  const inbox = target;
@@ -263,19 +271,19 @@ function listing(target, filter) {
263
271
  filter: normalizeFilter(filter),
264
272
  sort: "-lastSeen",
265
273
  view: null,
266
- label: inbox.options.label ?? inbox.name
274
+ label: inbox.options.label ?? humanize(inbox.name)
267
275
  };
268
276
  }
269
- const actionId = (action) => typeof action === "string" ? action : action.id;
277
+ const idOf = (action) => typeof action === "string" ? action : action.id;
270
278
  function button(input) {
271
279
  if (typeof input === "object" && "action" in input) return {
272
- action: actionId(input.action),
280
+ action: idOf(input.action),
273
281
  record: input.record ?? null,
274
282
  ...input.input && { input: JSON.parse(JSON.stringify(input.input)) },
275
283
  ...input.label && { label: input.label }
276
284
  };
277
285
  return {
278
- action: actionId(input),
286
+ action: idOf(input),
279
287
  record: null
280
288
  };
281
289
  }
@@ -284,7 +292,7 @@ function bindActions(blocks, resource, record) {
284
292
  const own = (action) => !action.includes(".") && kindOf(resource.actions[action]) === "action";
285
293
  const bind = (target) => own(target.action) ? {
286
294
  ...target,
287
- action: `${resource.name}.${target.action}`,
295
+ action: actionId(resource.name, target.action),
288
296
  record: target.record ?? record
289
297
  } : target;
290
298
  const value = (field) => field && typeof field === "object" && "edit" in field ? { edit: bind(field.edit) } : field;
@@ -403,7 +411,7 @@ const b = {
403
411
  }),
404
412
  edit: (value, action, options = {}) => ({ edit: {
405
413
  value: field(value),
406
- action: actionId(action),
414
+ action: idOf(action),
407
415
  record: options.record ?? null,
408
416
  field: options.field ?? null
409
417
  } })
@@ -411,6 +419,9 @@ const b = {
411
419
  function isPendingAttachment(block) {
412
420
  return block.type === "attachment" && "data" in block;
413
421
  }
422
+ function hasPendingAttachments(blocks) {
423
+ return blocks.some((block) => isPendingAttachment(block) || block.type === "columns" && block.columns.some(hasPendingAttachments));
424
+ }
414
425
  //#endregion
415
426
  //#region src/client/transport.ts
416
427
  const DEFAULT_URL = "https://app.pult.sh";
@@ -435,12 +446,13 @@ var Transport = class {
435
446
  this.key = parseKey(key);
436
447
  this.url = url.replace(/\/$/, "");
437
448
  }
438
- async request(method, path, body) {
439
- const payload = body === void 0 ? "" : JSON.stringify(body);
440
- return this.#fetch(method, path, payload, payload, "application/json");
449
+ request(method, path, body) {
450
+ return this.json(method, path, body === void 0 ? "" : JSON.stringify(body));
441
451
  }
442
- async upload(name, contentType, data) {
443
- const bytes = new Uint8Array(data instanceof Blob ? await data.arrayBuffer() : data);
452
+ json(method, path, json) {
453
+ return this.#fetch(method, path, json, json, "application/json");
454
+ }
455
+ async upload(name, contentType, bytes) {
444
456
  const hex = await sha256(bytes);
445
457
  const id = `${hex}:${name}:${contentType}`;
446
458
  const now = Date.now();
@@ -478,7 +490,7 @@ var Transport = class {
478
490
  }
479
491
  };
480
492
  //#endregion
481
- //#region src/define/flag.ts
493
+ //#region src/define/controls/flag.ts
482
494
  function flag(name, options = {}) {
483
495
  return {
484
496
  [KIND]: "flag",
@@ -505,6 +517,7 @@ function collect(modules) {
505
517
  pages: /* @__PURE__ */ new Map(),
506
518
  flags: /* @__PURE__ */ new Map(),
507
519
  notify: /* @__PURE__ */ new Map(),
520
+ spaces: /* @__PURE__ */ new Map(),
508
521
  status: null,
509
522
  config: null
510
523
  };
@@ -557,6 +570,16 @@ function collect(modules) {
557
570
  for (const guard of guards(flag)) add(guard.inbox);
558
571
  return;
559
572
  }
573
+ case "space": {
574
+ const space = value;
575
+ claim(found.spaces, space, "spaces");
576
+ if (space.home) add(space.home);
577
+ for (const inbox of space.options.inboxes ?? []) add(inbox);
578
+ for (const resource of space.options.resources ?? []) add(resource);
579
+ for (const page of space.options.pages ?? []) add(page);
580
+ for (const flag of space.options.flags ?? []) add(flag);
581
+ return;
582
+ }
560
583
  case "notify": {
561
584
  const rule = value;
562
585
  claim(found.notify, rule, "notifications");
@@ -635,4 +658,4 @@ function reviveDates(schema, value) {
635
658
  return value;
636
659
  }
637
660
  //#endregion
638
- export { mapBlocks as A, HEADER as C, sign as D, parseKey as E, FLAG_ACTION as M, HOME as N, verify as O, findActionDef as P, kindOf as S, NonceWindow as T, normalizeFilter as _, collect as a, KIND as b, guards as c, Transport as d, b as f, home as g, isPendingAttachment as h, validate as i, DEFAULT_STATES as j, eachBlock as k, DEFAULT_URL as l, fieldValues as m, reviveDates as n, findAction as o, bindActions as p, toJsonSchema as r, flag as s, ValidationError as t, PultError as u, page as v, refKey as w, captureOrigin as x, view as y };
661
+ export { mapBlocks as A, traceOrigins as C, sign as D, NonceWindow as E, HOME as F, actionId as I, findActionDef as L, valuesIn as M, DEFAULT_STATES as N, verify as O, FLAG_ACTION as P, kindOf as S, refKey as T, normalizeFilter as _, collect as a, captureOrigin as b, guards as c, Transport as d, b as f, isPendingAttachment as g, hasPendingAttachments as h, validate as i, shownValue as j, eachBlock as k, DEFAULT_URL as l, fieldValues as m, reviveDates as n, findAction as o, bindActions as p, toJsonSchema as r, flag as s, ValidationError as t, PultError as u, view as v, HEADER as w, humanize as x, KIND as y };
package/cli.d.mts DELETED
@@ -1 +0,0 @@
1
- export {}
package/stub.d.mts DELETED
@@ -1,11 +0,0 @@
1
- //#region src/build/stub.d.ts
2
- export declare const env: never;
3
- export declare const exports: never;
4
- export declare class WorkerEntrypoint {}
5
- export declare class DurableObject {}
6
- export declare class WorkflowEntrypoint {}
7
- export declare class RpcTarget {}
8
- export declare class EmailMessage {}
9
- export declare function waitUntil(): void;
10
- export declare function connect(): never;
11
- //#endregion