@timqi/pier 0.0.7 → 0.0.8

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/db.js CHANGED
@@ -145,6 +145,27 @@ const MIGRATIONS = [
145
145
  ALTER TABLE session_state ADD COLUMN cwd TEXT;
146
146
  ALTER TABLE session_state ADD COLUMN title TEXT;
147
147
  ALTER TABLE session_state ADD COLUMN created_at INTEGER;
148
+ `,
149
+ // 5 — the workbench can reach a browser that is not open (web/push.ts).
150
+ `
151
+ -- One row per browser that asked to be notified, exactly as the Push API
152
+ -- described it; a dead endpoint is deleted when its service says so.
153
+ CREATE TABLE push_subscriptions (
154
+ endpoint TEXT PRIMARY KEY,
155
+ p256dh TEXT NOT NULL,
156
+ auth TEXT NOT NULL,
157
+ label TEXT NOT NULL,
158
+ created_at INTEGER NOT NULL
159
+ );
160
+
161
+ -- This instance's VAPID identity: one key pair, minted on first use. Every
162
+ -- subscription above is bound to it, so it is never rotated on its own.
163
+ CREATE TABLE push_identity (
164
+ id INTEGER PRIMARY KEY CHECK (id = 1),
165
+ public_key TEXT NOT NULL,
166
+ private_key TEXT NOT NULL,
167
+ created_at INTEGER NOT NULL
168
+ );
148
169
  `,
149
170
  ];
150
171
  let shared;
package/dist/main.js CHANGED
@@ -32,6 +32,7 @@ import { startUpdate, unitPath, updaterProblem } from "./service.js";
32
32
  import { SettingsStore } from "./settings.js";
33
33
  import { startAutoUpdate, UpdateCheck } from "./update.js";
34
34
  import { AuthStore, registerAuthRoutes, requireAuth } from "./web/auth.js";
35
+ import { PushStore, registerPushRoutes } from "./web/push.js";
35
36
  import { SessionStateStore } from "./web/session-state.js";
36
37
  import { createServer } from "./web/server.js";
37
38
  import { attachTerminal } from "./web/terminal.js";
@@ -259,11 +260,23 @@ registerAuthRoutes(app, auth);
259
260
  registerTaskRoutes(app, tasks, { factory, router });
260
261
  registerChannelRoutes(app, channelStore, channels);
261
262
  registerBoardRoutes(app);
263
+ const sessionState = new SessionStateStore(db);
264
+ // The workbench's notifications to a browser that is not open. Composed here,
265
+ // beside the other surfaces: it consumes the same event stream the web server
266
+ // does, and neither one runs the other.
267
+ registerPushRoutes(app, {
268
+ store: new PushStore(db),
269
+ hub,
270
+ unread: (id) => sessionState.unread(id),
271
+ channelOf: (id) => router.conversationOf(id)?.channelId,
272
+ name: (id) => sessionState.name(id),
273
+ publicUrl: () => settings.get().publicUrl,
274
+ });
262
275
  app.route("/", createServer({
263
276
  factory,
264
277
  router,
265
278
  hub,
266
- sessions: new SessionStateStore(db),
279
+ sessions: sessionState,
267
280
  config: piConfig,
268
281
  providers: factory,
269
282
  settings,