@drift-beacon/plugin 0.1.0 → 0.1.1
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/cli.js +0 -8
- package/dist/dev.js +0 -7
- package/dist/errors.js +0 -1
- package/dist/index.js +0 -5
- package/dist/internal/collection.js +0 -4
- package/dist/internal/compatibility.js +0 -11
- package/dist/internal/json-equal.js +0 -1
- package/dist/internal/manifest.js +0 -1
- package/dist/internal/models.js +0 -43
- package/dist/internal/package-layout.js +0 -7
- package/dist/internal/protocol.js +0 -1
- package/dist/main.js +0 -11
- package/dist/pack.js +0 -15
- package/dist/prepare.js +0 -18
- package/dist/types.js +0 -9
- package/dist/ui.js +0 -19
- package/dist/version.js +0 -4
- package/dist/vite.js +1 -66
- package/package.json +11 -4
- package/dist/cli.d.ts +0 -2
- package/dist/dev.d.ts +0 -38
- package/dist/internal/actions.d.ts +0 -35
- package/dist/internal/collection.d.ts +0 -15
- package/dist/internal/compatibility.d.ts +0 -26
- package/dist/internal/json-equal.d.ts +0 -3
- package/dist/internal/manifest.d.ts +0 -51
- package/dist/internal/models.d.ts +0 -62
- package/dist/internal/package-layout.d.ts +0 -21
- package/dist/internal/protocol.d.ts +0 -96
- package/dist/internal/rows.d.ts +0 -41
- package/dist/internal.d.ts +0 -17
- package/dist/internal.js +0 -13
- package/dist/pack.d.ts +0 -24
- package/dist/prepare.d.ts +0 -28
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `dbplugin` (Drift Beacon plugins), run through `bin/dbplugin.js`:
|
|
3
|
-
*
|
|
4
|
-
* dbplugin prepare [root] Generate .drift-beacon/ (config types and tsconfigs). Lenient: a manifest
|
|
5
|
-
* problem only warns, because this runs as the plugin's postinstall.
|
|
6
|
-
* dbplugin pack [root] [--out <dir>] Typecheck, build fresh and write <out>/<id>.zip (default releases/).
|
|
7
|
-
* Prints only the result JSON on stdout.
|
|
8
|
-
*/
|
|
9
1
|
import path from "node:path";
|
|
10
2
|
import { parseArgs } from "node:util";
|
|
11
3
|
import { pack } from "./pack.js";
|
package/dist/dev.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The `pnpm dev` handshake between `driftBeacon()` and the Drift Beacon server. The dev tool writes a
|
|
3
|
-
* marker into the package's `dist/`; the server polls for it, connects to Vite's HMR socket and trusts
|
|
4
|
-
* the socket only after a `welcome` whose `session` equals the marker's. Messages travel as Vite custom
|
|
5
|
-
* events (`{ type: "custom", event, data }`). All wording is rendered on the server; the tool only prints.
|
|
6
|
-
*/
|
|
7
|
-
/** File name of the marker in `dist/`. Written as tmp, then renamed, synchronously. Never packed. */
|
|
8
1
|
export const DEV_MARKER = ".drift-beacon-dev.json";
|
package/dist/errors.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Drift Beacon plugin SDK: the API for main code (runs on the server). Plugin UIs import from `@drift-beacon/plugin/ui`.
|
|
3
|
-
*
|
|
4
|
-
* At run time the plugin host supplies this module, so `driftBeacon()` keeps it external when building main.
|
|
5
|
-
*/
|
|
6
1
|
export { PluginError } from "./errors.js";
|
|
7
2
|
export { definePlugin } from "./main.js";
|
|
8
3
|
export { API_VERSION } from "./version.js";
|
|
@@ -7,10 +7,6 @@ function deepFreeze(value) {
|
|
|
7
7
|
}
|
|
8
8
|
return value;
|
|
9
9
|
}
|
|
10
|
-
/**
|
|
11
|
-
* A collection of plain rows keyed by id, frozen as they arrive. `replace` applies a full set of rows, keeps the
|
|
12
|
-
* object of every unchanged row (so identity only changes when data does) and reports the changes.
|
|
13
|
-
*/
|
|
14
10
|
export class Collection {
|
|
15
11
|
rows = new Map();
|
|
16
12
|
cachedList = null;
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { API_VERSION } from "../version.js";
|
|
2
|
-
/**
|
|
3
|
-
* API versions this build of Drift Beacon runs: the newest minor of each supported major.
|
|
4
|
-
* Before 1.0 only the current version is listed, because every 0.x minor may break plugins.
|
|
5
|
-
* From 1.0, the previous major stays listed for at least six months after its successor ships.
|
|
6
|
-
*/
|
|
7
2
|
export const SUPPORTED_API_VERSIONS = [API_VERSION];
|
|
8
3
|
const API_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
9
|
-
/** Parse a `major.minor` API version; null when malformed. */
|
|
10
4
|
export function parseApiVersion(value) {
|
|
11
5
|
if (typeof value !== "string")
|
|
12
6
|
return null;
|
|
@@ -15,11 +9,6 @@ export function parseApiVersion(value) {
|
|
|
15
9
|
return null;
|
|
16
10
|
return { major: Number(match[1]), minor: Number(match[2]) };
|
|
17
11
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Whether a plugin built for `pluginVersion` runs on a build supporting `supported`.
|
|
20
|
-
* Before 1.0 the minor must match exactly; from 1.0 the major must match and the plugin's
|
|
21
|
-
* minor must not be newer than the host's.
|
|
22
|
-
*/
|
|
23
12
|
export function checkApiCompatibility(pluginVersion, supported = SUPPORTED_API_VERSIONS) {
|
|
24
13
|
const plugin = parseApiVersion(pluginVersion);
|
|
25
14
|
if (!plugin) {
|
|
@@ -3,7 +3,6 @@ const STABLE_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:\+[0-9A-Za-z
|
|
|
3
3
|
export const isStableVersion = (value) => typeof value === "string" &&
|
|
4
4
|
STABLE_VERSION.test(value) &&
|
|
5
5
|
(value.split("+")[0] ?? "").split(".").every((part) => Number.isSafeInteger(Number(part)));
|
|
6
|
-
/** Throws a readable error when `manifest` is not a valid plugin manifest. Shared by the server and the pack tool. */
|
|
7
6
|
export function validateManifest(manifest) {
|
|
8
7
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest))
|
|
9
8
|
throw new Error("Invalid plugin manifest");
|
package/dist/internal/models.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The models plugins see: `Activity`, `Category` and `Session` objects over the workspace rows.
|
|
3
|
-
*
|
|
4
|
-
* One `WorkspaceModels` per `ctx`. The plugin host builds it for main code; the UI client builds it
|
|
5
|
-
* inside every UI bundle, so this file is part of the UI wire contract: change it only additively
|
|
6
|
-
* within an API version.
|
|
7
|
-
*
|
|
8
|
-
* Every read goes to the latest snapshot in the collections, synchronously. Nothing is applied ahead
|
|
9
|
-
* of a snapshot. Lists are computed once per snapshot, so they keep their identity until the data
|
|
10
|
-
* changes.
|
|
11
|
-
*/
|
|
12
1
|
import { PluginError } from "../errors.js";
|
|
13
2
|
const ACTIVITY_FIELDS = [
|
|
14
3
|
"id",
|
|
@@ -43,10 +32,6 @@ const SESSION_FIELDS = [
|
|
|
43
32
|
];
|
|
44
33
|
const gone = (what) => Promise.reject(new PluginError("not-found", `${what} no longer exists`));
|
|
45
34
|
const compareText = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
46
|
-
/**
|
|
47
|
-
* Give a model its data fields as enumerable getters, so spreading, `JSON.stringify` and
|
|
48
|
-
* `postMessage` copy the current values, then freeze it.
|
|
49
|
-
*/
|
|
50
35
|
function seal(model, fields, data) {
|
|
51
36
|
for (const field of fields) {
|
|
52
37
|
Object.defineProperty(model, field, { enumerable: true, get: () => data()[field] });
|
|
@@ -170,11 +155,9 @@ export class WorkspaceModels {
|
|
|
170
155
|
#activities = new Map();
|
|
171
156
|
#categories = new Map();
|
|
172
157
|
#sessions = new Map();
|
|
173
|
-
/** The last row seen for each id, so a model whose row was removed keeps its values. */
|
|
174
158
|
#lastActivity = new Map();
|
|
175
159
|
#lastCategory = new Map();
|
|
176
160
|
#lastSession = new Map();
|
|
177
|
-
/** Session rows with `Date` fields, one per row version. Built per `ctx`: a `Date` can't be frozen. */
|
|
178
161
|
#sessionData = new WeakMap();
|
|
179
162
|
#lists = new Map();
|
|
180
163
|
#listsSnapshot = [];
|
|
@@ -183,7 +166,6 @@ export class WorkspaceModels {
|
|
|
183
166
|
this.rows = options.rows;
|
|
184
167
|
this.#actions = options.actions;
|
|
185
168
|
}
|
|
186
|
-
/** The reads and actions for `ctx`. */
|
|
187
169
|
apis() {
|
|
188
170
|
return {
|
|
189
171
|
activities: {
|
|
@@ -205,9 +187,6 @@ export class WorkspaceModels {
|
|
|
205
187
|
},
|
|
206
188
|
};
|
|
207
189
|
}
|
|
208
|
-
// --------------------------------------------------------------------------
|
|
209
|
-
// Reads
|
|
210
|
-
// --------------------------------------------------------------------------
|
|
211
190
|
activity(id) {
|
|
212
191
|
return this.rows.activities.get(id) ? this.#activityModel(id) : undefined;
|
|
213
192
|
}
|
|
@@ -217,7 +196,6 @@ export class WorkspaceModels {
|
|
|
217
196
|
session(id) {
|
|
218
197
|
return this.rows.sessions.get(id) ? this.#sessionModel(id) : undefined;
|
|
219
198
|
}
|
|
220
|
-
/** In the app's order: by category (uncategorized last), then `sortOrder`, then name. */
|
|
221
199
|
activities(filter = {}) {
|
|
222
200
|
const { categoryId, trackingType, includeArchived = false } = filter;
|
|
223
201
|
const key = {
|
|
@@ -241,13 +219,11 @@ export class WorkspaceModels {
|
|
|
241
219
|
.map((row) => this.#activityModel(row.id));
|
|
242
220
|
});
|
|
243
221
|
}
|
|
244
|
-
/** By `sortOrder`, then name. */
|
|
245
222
|
categories() {
|
|
246
223
|
return this.#list({ list: "categories" }, () => [...this.rows.categories.list()]
|
|
247
224
|
.sort((a, b) => a.sortOrder - b.sortOrder || compareText(a.name, b.name) || compareText(a.id, b.id))
|
|
248
225
|
.map((row) => this.#categoryModel(row.id)));
|
|
249
226
|
}
|
|
250
|
-
/** Newest first. */
|
|
251
227
|
sessions(filter = {}) {
|
|
252
228
|
const { activityId, status, mine = false } = filter;
|
|
253
229
|
return this.#list({ list: "sessions", activityId, status, mine }, () => this.rows.sessions
|
|
@@ -259,9 +235,6 @@ export class WorkspaceModels {
|
|
|
259
235
|
.sort((a, b) => b.at - a.at || compareText(a.row.id, b.row.id))
|
|
260
236
|
.map(({ row }) => this.#sessionModel(row.id)));
|
|
261
237
|
}
|
|
262
|
-
// --------------------------------------------------------------------------
|
|
263
|
-
// Actions
|
|
264
|
-
// --------------------------------------------------------------------------
|
|
265
238
|
async start(activityId) {
|
|
266
239
|
return this.#result(await this.#actions.start(activityId));
|
|
267
240
|
}
|
|
@@ -274,10 +247,6 @@ export class WorkspaceModels {
|
|
|
274
247
|
async discard(sessionId) {
|
|
275
248
|
await this.#actions.discard(sessionId);
|
|
276
249
|
}
|
|
277
|
-
// --------------------------------------------------------------------------
|
|
278
|
-
// Deliveries
|
|
279
|
-
// --------------------------------------------------------------------------
|
|
280
|
-
/** Turn the row changes of a snapshot into model changes. Call it after the collections were replaced. */
|
|
281
250
|
update(changes) {
|
|
282
251
|
return {
|
|
283
252
|
activities: changes.activities.map((change) => this.#change(change, this.#lastActivity, (id) => this.#activityModel(id), (row) => row)),
|
|
@@ -285,18 +254,11 @@ export class WorkspaceModels {
|
|
|
285
254
|
sessions: changes.sessions.map((change) => this.#change(change, this.#lastSession, (id) => this.#sessionModel(id), (row) => this.#toSessionData(row))),
|
|
286
255
|
};
|
|
287
256
|
}
|
|
288
|
-
/**
|
|
289
|
-
* The model for a session the app sent outside a snapshot (a live event or an action result):
|
|
290
|
-
* the snapshot's model, or, when the row isn't in the snapshot, a removed model holding these values.
|
|
291
|
-
*/
|
|
292
257
|
sessionFrom(row) {
|
|
293
258
|
if (!this.rows.sessions.get(row.id))
|
|
294
259
|
this.#lastSession.set(row.id, row);
|
|
295
260
|
return this.#sessionModel(row.id);
|
|
296
261
|
}
|
|
297
|
-
// --------------------------------------------------------------------------
|
|
298
|
-
// Rows, for the models
|
|
299
|
-
// --------------------------------------------------------------------------
|
|
300
262
|
activityRow(id) {
|
|
301
263
|
return latest(this.rows.activities.get(id), this.#lastActivity, id);
|
|
302
264
|
}
|
|
@@ -306,9 +268,6 @@ export class WorkspaceModels {
|
|
|
306
268
|
sessionData(id) {
|
|
307
269
|
return this.#toSessionData(latest(this.rows.sessions.get(id), this.#lastSession, id));
|
|
308
270
|
}
|
|
309
|
-
// --------------------------------------------------------------------------
|
|
310
|
-
// Internals
|
|
311
|
-
// --------------------------------------------------------------------------
|
|
312
271
|
#activityModel(id) {
|
|
313
272
|
let model = this.#activities.get(id);
|
|
314
273
|
if (!model) {
|
|
@@ -357,7 +316,6 @@ export class WorkspaceModels {
|
|
|
357
316
|
throw new PluginError("failed", "Drift Beacon did not return the session");
|
|
358
317
|
return this.sessionFrom(value);
|
|
359
318
|
}
|
|
360
|
-
/** A list computed once per snapshot: the same frozen array until any collection changes. */
|
|
361
319
|
#list(key, compute) {
|
|
362
320
|
const snapshot = [this.rows.activities.list(), this.rows.categories.list(), this.rows.sessions.list()];
|
|
363
321
|
if (snapshot.some((list, index) => list !== this.#listsSnapshot[index])) {
|
|
@@ -373,7 +331,6 @@ export class WorkspaceModels {
|
|
|
373
331
|
return list;
|
|
374
332
|
}
|
|
375
333
|
}
|
|
376
|
-
/** The row in the snapshot, remembered as the last one seen; otherwise the last one seen. */
|
|
377
334
|
function latest(row, last, id) {
|
|
378
335
|
if (row !== undefined) {
|
|
379
336
|
if (last.get(id) !== row)
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The plugin package: `manifest.json`, `package.json`, `main/index.js` (plus chunks) and `ui/index.html`
|
|
3
|
-
* (plus assets and the manifest icon). Shared by the pack tool and the server. Pure: the web app bundles
|
|
4
|
-
* `/internal`, so no `node:` imports.
|
|
5
|
-
*/
|
|
6
1
|
export const PACKAGE_LIMITS = {
|
|
7
2
|
entries: 2000,
|
|
8
3
|
fileBytes: 32 * 2 ** 20,
|
|
@@ -10,10 +5,8 @@ export const PACKAGE_LIMITS = {
|
|
|
10
5
|
archiveBytes: 32 * 2 ** 20,
|
|
11
6
|
manifestBytes: 256 * 2 ** 10,
|
|
12
7
|
};
|
|
13
|
-
/** The `package.json` every package gets: main is ESM. */
|
|
14
8
|
export const PACKAGE_JSON = { type: "module", private: true };
|
|
15
9
|
export const REQUIRED_FILES = ["main/index.js", "ui/index.html"];
|
|
16
|
-
/** manifest.json, package.json, main/** and ui/** (directories: main, ui and below). `name` has no trailing slash. */
|
|
17
10
|
export const isPackagePath = (name, directory) => name.startsWith("main/") ||
|
|
18
11
|
name.startsWith("ui/") ||
|
|
19
12
|
(directory ? name === "main" || name === "ui" : name === "manifest.json" || name === "package.json");
|
package/dist/main.js
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Define a plugin's main code. Export the result as the module's default export:
|
|
3
|
-
*
|
|
4
|
-
* ```ts
|
|
5
|
-
* export default definePlugin({
|
|
6
|
-
* onStart(ctx) {
|
|
7
|
-
* ctx.mqtt.subscribe(ctx.config.mqttTopic, (message) => ctx.log.info(message.payload));
|
|
8
|
-
* },
|
|
9
|
-
* });
|
|
10
|
-
* ```
|
|
11
|
-
*/
|
|
12
1
|
export function definePlugin(definition) {
|
|
13
2
|
return definition;
|
|
14
3
|
}
|
package/dist/pack.js
CHANGED
|
@@ -6,10 +6,6 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
10
|
-
* Release packaging. `packDirectory` zips a finished package folder (`dbplugin pack` and the server's
|
|
11
|
-
* `plugin:install`); `pack` typechecks a plugin package, builds it fresh into a temp folder and packs that.
|
|
12
|
-
*/
|
|
13
9
|
import { spawnSync } from "node:child_process";
|
|
14
10
|
import { existsSync } from "node:fs";
|
|
15
11
|
import { lstat, mkdir, mkdtemp, readdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
@@ -20,10 +16,6 @@ import { pathToFileURL } from "node:url";
|
|
|
20
16
|
import { strToU8, zipSync } from "fflate";
|
|
21
17
|
import { PACKAGE_JSON, PACKAGE_LIMITS, REQUIRED_FILES } from "./internal/package-layout.js";
|
|
22
18
|
import { loadManifest, prepare } from "./prepare.js";
|
|
23
|
-
/**
|
|
24
|
-
* Zip the package in `dir` into `<outDir>/<id>.zip`: its manifest, a generated `package.json`, and `main/**`
|
|
25
|
-
* and `ui/**`. Anything else in `dir` (the dev marker, its `package.json`) is left out. Never runs plugin code.
|
|
26
|
-
*/
|
|
27
19
|
export async function packDirectory(dir, outDir) {
|
|
28
20
|
const source = path.resolve(dir);
|
|
29
21
|
const { manifest, bytes: manifestBytes } = loadManifest(source);
|
|
@@ -87,12 +79,6 @@ export async function packDirectory(dir, outDir) {
|
|
|
87
79
|
await writeFile(archivePath, archive);
|
|
88
80
|
return { id: manifest.id, version: manifest.version, tag: `${manifest.id}-${manifest.version}`, asset, archivePath };
|
|
89
81
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Build a release of the plugin package at `root`: prepare, typecheck main and UI with the package's own
|
|
92
|
-
* TypeScript, `vite build` into a fresh temp folder with the package's own Vite, then `packDirectory`. The
|
|
93
|
-
* package's `dist/` is never read or written. Everything printed meanwhile goes to stderr, so a caller's
|
|
94
|
-
* stdout carries only the result.
|
|
95
|
-
*/
|
|
96
82
|
export async function pack(root, options = {}) {
|
|
97
83
|
const pkg = path.resolve(root);
|
|
98
84
|
const write = process.stdout.write;
|
|
@@ -101,7 +87,6 @@ export async function pack(root, options = {}) {
|
|
|
101
87
|
try {
|
|
102
88
|
prepare(pkg, { strict: true });
|
|
103
89
|
const require = createRequire(path.join(pkg, "package.json"));
|
|
104
|
-
// Found through its package.json `bin`: TypeScript 7 doesn't export `typescript/bin/tsc`.
|
|
105
90
|
const typescript = require.resolve("typescript/package.json");
|
|
106
91
|
const { bin } = JSON.parse(await readFile(typescript, "utf8"));
|
|
107
92
|
const tsc = path.join(path.dirname(typescript), bin.tsc);
|
package/dist/prepare.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Writes a plugin package's generated `.drift-beacon/` folder: `config.d.ts` (the `ctx.config` types from
|
|
3
|
-
* manifest.json), the main and UI tsconfigs, and a `.gitignore` that ignores the folder itself. Also reads
|
|
4
|
-
* and checks manifests for `driftBeacon()` and `dbplugin pack` (`loadManifest`).
|
|
5
|
-
*/
|
|
6
1
|
import { existsSync, lstatSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
2
|
import path from "node:path";
|
|
8
3
|
import { checkApiCompatibility } from "./internal/compatibility.js";
|
|
@@ -22,7 +17,6 @@ const COMPILER_OPTIONS = {
|
|
|
22
17
|
noFallthroughCasesInSwitch: true,
|
|
23
18
|
noUncheckedSideEffectImports: true,
|
|
24
19
|
};
|
|
25
|
-
// Explicit `types` keep UI typings (React, three.js) out of main; `vite/client` allows CSS and asset imports in the UI.
|
|
26
20
|
const TSCONFIG_MAIN = {
|
|
27
21
|
compilerOptions: { ...COMPILER_OPTIONS, lib: ["ES2023"], types: ["node"] },
|
|
28
22
|
include: ["../main/src", "../vite.config.ts", "./config.d.ts"],
|
|
@@ -57,11 +51,6 @@ export function prepare(root, { strict }) {
|
|
|
57
51
|
writeIfChanged(path.join(out, "tsconfig.ui.json"), `${JSON.stringify(TSCONFIG_UI, null, 2)}\n`);
|
|
58
52
|
return loaded;
|
|
59
53
|
}
|
|
60
|
-
/**
|
|
61
|
-
* `<root>/manifest.json`, the one read of a manifest in the SDK (dev, build, prepare and pack): a regular
|
|
62
|
-
* file within the package limit, valid, and for an `apiVersion` this SDK runs (the server's check). The
|
|
63
|
-
* error names the file.
|
|
64
|
-
*/
|
|
65
54
|
export function loadManifest(root) {
|
|
66
55
|
const file = path.join(root, "manifest.json");
|
|
67
56
|
let manifest;
|
|
@@ -85,12 +74,6 @@ export function loadManifest(root) {
|
|
|
85
74
|
throw new Error(`${file}: ${compatibility.message}`);
|
|
86
75
|
return { manifest, bytes };
|
|
87
76
|
}
|
|
88
|
-
/**
|
|
89
|
-
* Augments the SDK's `PluginConfig`. Mirrors the server's config validation: a setting can be missing
|
|
90
|
-
* unless it is required or has a default. The type-only import makes this a module, so `declare module`
|
|
91
|
-
* augments instead of declaring an ambient module, and it loads the SDK entry into every program: the UI
|
|
92
|
-
* imports only `@drift-beacon/plugin/ui`, and an augmentation of a module the program never loads has no effect.
|
|
93
|
-
*/
|
|
94
77
|
function configTypes(configuration) {
|
|
95
78
|
const lines = [
|
|
96
79
|
"// Generated by dbplugin prepare from manifest.json. Do not edit.",
|
|
@@ -113,7 +96,6 @@ const valueType = (item) => item.type !== "dropdown"
|
|
|
113
96
|
: item.data.length === 0
|
|
114
97
|
? "string"
|
|
115
98
|
: [...new Set(item.data.map((option) => JSON.stringify(option.value)))].join(" | ");
|
|
116
|
-
/** Leaves the file (and its mtime) alone when it already has `content`, so editors and watchers stay quiet. */
|
|
117
99
|
function writeIfChanged(file, content) {
|
|
118
100
|
if (existsSync(file) && readFileSync(file, "utf8") === content)
|
|
119
101
|
return;
|
package/dist/types.js
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Data and APIs shared by plugin main code (server) and UIs (iframe).
|
|
3
|
-
*
|
|
4
|
-
* Workspace data comes as models: an `Activity`, `Category` or `Session` with its fields, links,
|
|
5
|
-
* derived values and actions. Models read the latest snapshot the app sent, synchronously; there is
|
|
6
|
-
* one model per row for the life of a `ctx`, and `model.data` is its plain, frozen row. Later API
|
|
7
|
-
* versions may add fields and new values to string unions such as `trackingType`, so plugins must
|
|
8
|
-
* ignore what they don't recognise.
|
|
9
|
-
*/
|
|
10
1
|
export {};
|
package/dist/ui.js
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The UI client: runs inside a plugin's iframe and talks to the Drift Beacon web app.
|
|
3
|
-
*
|
|
4
|
-
* ```ts
|
|
5
|
-
* const ctx = await connect();
|
|
6
|
-
* ctx.onDataChange(render);
|
|
7
|
-
* ```
|
|
8
|
-
*/
|
|
9
1
|
import { PluginError } from "./errors.js";
|
|
10
2
|
import { Collection } from "./internal/collection.js";
|
|
11
3
|
import { jsonEqual } from "./internal/json-equal.js";
|
|
@@ -17,7 +9,6 @@ export { API_VERSION } from "./version.js";
|
|
|
17
9
|
const HELLO_INTERVAL_MS = 250;
|
|
18
10
|
const REQUEST_TIMEOUT_MS = 10_000;
|
|
19
11
|
let connection = null;
|
|
20
|
-
/** Connect to the Drift Beacon web app. Resolves once the app accepts this UI; later calls return the same context. */
|
|
21
12
|
export function connect(options = {}) {
|
|
22
13
|
connection ??= open(options.timeoutMs ?? 10_000);
|
|
23
14
|
return connection;
|
|
@@ -59,7 +50,6 @@ function open(timeoutMs) {
|
|
|
59
50
|
};
|
|
60
51
|
window.addEventListener("message", onMessage);
|
|
61
52
|
const sayHello = () => post({ channel: UI_CHANNEL, type: "hello", apiVersion: API_VERSION });
|
|
62
|
-
// Repeat until answered: the app may still be setting up when the UI first loads.
|
|
63
53
|
const hello = setInterval(sayHello, HELLO_INTERVAL_MS);
|
|
64
54
|
sayHello();
|
|
65
55
|
const timeout = setTimeout(() => {
|
|
@@ -86,12 +76,7 @@ class UiClient {
|
|
|
86
76
|
storageListeners = new Set();
|
|
87
77
|
storage = new Map();
|
|
88
78
|
serverStorage;
|
|
89
|
-
/** Keys with writes the app hasn't answered; older pushes must not revert them. */
|
|
90
79
|
pendingWrites = new Map();
|
|
91
|
-
/**
|
|
92
|
-
* Keys written since the app last sent storage, with the latest write's ID. The app may answer a
|
|
93
|
-
* write before its next push, so an answered write stays in place until that push arrives.
|
|
94
|
-
*/
|
|
95
80
|
writesSincePush = new Map();
|
|
96
81
|
nextWrite = 0;
|
|
97
82
|
pending = new Map();
|
|
@@ -140,7 +125,6 @@ class UiClient {
|
|
|
140
125
|
}
|
|
141
126
|
receive(message) {
|
|
142
127
|
if (message.type === "welcome") {
|
|
143
|
-
// A reconnect: identity is unchanged, so only the state is new.
|
|
144
128
|
this.receive({
|
|
145
129
|
channel: message.channel,
|
|
146
130
|
type: "state",
|
|
@@ -174,7 +158,6 @@ class UiClient {
|
|
|
174
158
|
}
|
|
175
159
|
notify(this.dataListeners, (listener) => listener());
|
|
176
160
|
}
|
|
177
|
-
/** Replace all three collections before telling anyone, so callbacks see one consistent snapshot. */
|
|
178
161
|
applyData(data) {
|
|
179
162
|
const changes = this.models.update({
|
|
180
163
|
activities: this.rows.activities.replace(data.activities),
|
|
@@ -188,7 +171,6 @@ class UiClient {
|
|
|
188
171
|
for (const change of changes.sessions)
|
|
189
172
|
notify(this.sessionListeners, (listener) => listener(change));
|
|
190
173
|
}
|
|
191
|
-
/** Apply the app's storage, keeping local values for keys with unconfirmed writes. Returns whether anything changed. */
|
|
192
174
|
reconcileStorage() {
|
|
193
175
|
const isProtected = (key) => this.pendingWrites.has(key) || this.writesSincePush.has(key);
|
|
194
176
|
const next = new Map();
|
|
@@ -225,7 +207,6 @@ class UiClient {
|
|
|
225
207
|
: { method: "storage.set", params: { key, value } });
|
|
226
208
|
}
|
|
227
209
|
catch (error) {
|
|
228
|
-
// Roll back to the app's value, unless a later local write replaced this one.
|
|
229
210
|
if (this.writesSincePush.get(key) === writeId)
|
|
230
211
|
this.writesSincePush.delete(key);
|
|
231
212
|
throw error;
|
package/dist/version.js
CHANGED
package/dist/vite.js
CHANGED
|
@@ -6,18 +6,6 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
6
6
|
}
|
|
7
7
|
return path;
|
|
8
8
|
};
|
|
9
|
-
/**
|
|
10
|
-
* `driftBeacon()` (`@drift-beacon/plugin/vite`): the Vite plugin of a plugin package. The UI is the author's
|
|
11
|
-
* own Vite app rooted at `ui/`; this plugin builds main next to it, so `dist/` is exactly the release package.
|
|
12
|
-
*
|
|
13
|
-
* `vite build` builds main once the UI is written. `vite` (`pnpm dev`) serves the UI with HMR, watch-builds main
|
|
14
|
-
* into `dist/` and keeps the manifest, the icon and the config types in sync. It writes a marker (dev.ts) that
|
|
15
|
-
* the Drift Beacon server polls; the server then connects to Vite's HMR socket and sends lines to print here.
|
|
16
|
-
*
|
|
17
|
-
* Through `link:`, a bare `vite` import from here would resolve to Cartridge's copy, whose types never match
|
|
18
|
-
* another copy's. So vite is only a type here: at run time the plugin loads the project's own vite, and the
|
|
19
|
-
* public signature names no vite type.
|
|
20
|
-
*/
|
|
21
9
|
import { createHash, randomUUID } from "node:crypto";
|
|
22
10
|
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
23
11
|
import { createRequire } from "node:module";
|
|
@@ -27,12 +15,7 @@ import { stripVTControlCharacters, styleText } from "node:util";
|
|
|
27
15
|
import { DEV_MARKER } from "./dev.js";
|
|
28
16
|
import { PACKAGE_JSON } from "./internal/package-layout.js";
|
|
29
17
|
import { prepare } from "./prepare.js";
|
|
30
|
-
/** How long `pnpm dev` waits for a Drift Beacon server before saying how to connect one. */
|
|
31
18
|
const HINT_DELAY_MS = 5_000;
|
|
32
|
-
/**
|
|
33
|
-
* The Vite plugin for a Drift Beacon plugin package: `plugins: [driftBeacon()]`. It owns `root`, `base` and
|
|
34
|
-
* `build.outDir`. Typed as `{ name: string }` so it fits any Vite version's `plugins`.
|
|
35
|
-
*/
|
|
36
19
|
export function driftBeacon() {
|
|
37
20
|
let pkg = "";
|
|
38
21
|
let dist = "";
|
|
@@ -44,7 +27,6 @@ export function driftBeacon() {
|
|
|
44
27
|
if (env.isPreview)
|
|
45
28
|
return;
|
|
46
29
|
pkg = path.resolve(config.root ?? process.cwd());
|
|
47
|
-
// Read, not assumed: `dbplugin pack` redirects the whole build into a temp folder through `build.outDir`.
|
|
48
30
|
dist = config.build?.outDir ? path.resolve(pkg, config.build.outDir) : path.join(pkg, "dist");
|
|
49
31
|
for (const file of ["ui/index.html", "main/src/index.ts"]) {
|
|
50
32
|
if (!existsSync(path.join(pkg, file)))
|
|
@@ -55,14 +37,11 @@ export function driftBeacon() {
|
|
|
55
37
|
throw new Error("driftBeacon(): a custom server.hmr port or path is not supported");
|
|
56
38
|
}
|
|
57
39
|
({ manifest, bytes: manifestBytes } = prepare(pkg, { strict: true }));
|
|
58
|
-
// `dist/ui` is outside the root `ui/`, so Vite only empties it when asked to.
|
|
59
40
|
return { root: path.join(pkg, "ui"), base: "./", build: { outDir: path.join(dist, "ui"), emptyOutDir: true } };
|
|
60
41
|
},
|
|
61
|
-
// `vite` (`pnpm dev`). A Vite restart creates the new server before closing the old one: both share the state.
|
|
62
42
|
configureServer(server) {
|
|
63
43
|
serveDev(server, devStates.get(pkg) ?? startDev(pkg, dist, manifest, manifestBytes, server.config.logger));
|
|
64
44
|
},
|
|
65
|
-
// `vite build` (and `dbplugin pack`). Runs after the UI is written (and Vite has copied `ui/public/` into `dist/ui/`).
|
|
66
45
|
async writeBundle() {
|
|
67
46
|
const vite = await loadVite(pkg);
|
|
68
47
|
await vite.build(mainBuild(vite, pkg, { outDir: path.join(dist, "main"), minify: true, sourcemap: false, logLevel: "warn" }));
|
|
@@ -73,16 +52,12 @@ export function driftBeacon() {
|
|
|
73
52
|
};
|
|
74
53
|
return plugin;
|
|
75
54
|
}
|
|
76
|
-
/** The project's own vite: through `link:`, a bare import would resolve to the SDK's copy. */
|
|
77
55
|
const loadVite = async (pkg) => import(__rewriteRelativeImportExtension(pathToFileURL(createRequire(path.join(pkg, "package.json")).resolve("vite")).href));
|
|
78
|
-
/** Main as one ESM file, with every dependency bundled except the SDK, which the plugin host supplies. */
|
|
79
56
|
function mainBuild(vite, pkg, options) {
|
|
80
|
-
// One file on both Vite 7 (Rollup) and Vite 8 (Rolldown, which deprecates `inlineDynamicImports`).
|
|
81
57
|
const single = "rolldownVersion" in vite ? { codeSplitting: false } : { inlineDynamicImports: true };
|
|
82
58
|
return {
|
|
83
59
|
configFile: false,
|
|
84
60
|
root: pkg,
|
|
85
|
-
// Vite copies publicDir in every build: a stray `<pkg>/public/` must not reach `dist/main/`.
|
|
86
61
|
publicDir: false,
|
|
87
62
|
logLevel: options.logLevel,
|
|
88
63
|
build: {
|
|
@@ -101,13 +76,10 @@ function mainBuild(vite, pkg, options) {
|
|
|
101
76
|
ssr: { noExternal: true },
|
|
102
77
|
};
|
|
103
78
|
}
|
|
104
|
-
// On globalThis, so the state survives whatever reloads this module; keyed by package root, so one process
|
|
105
|
-
// (a test file) can serve several roots.
|
|
106
79
|
const DEV_STATES = Symbol.for("drift-beacon.dev");
|
|
107
80
|
const shared = globalThis;
|
|
108
81
|
shared[DEV_STATES] ??= new Map();
|
|
109
82
|
const devStates = shared[DEV_STATES];
|
|
110
|
-
/** Once per root: seed `dist/` and start the main watch build. */
|
|
111
83
|
function startDev(pkg, dist, manifest, bytes, logger) {
|
|
112
84
|
writeAtomic(path.join(dist, "manifest.json"), bytes);
|
|
113
85
|
writeAtomic(path.join(dist, "package.json"), `${JSON.stringify(PACKAGE_JSON, null, 2)}\n`);
|
|
@@ -133,16 +105,11 @@ function startDev(pkg, dist, manifest, bytes, logger) {
|
|
|
133
105
|
});
|
|
134
106
|
return state;
|
|
135
107
|
}
|
|
136
|
-
/**
|
|
137
|
-
* Builds main into `.drift-beacon/main-next/` on every save, then moves the files into `dist/main/`: never a
|
|
138
|
-
* half-written bundle in `dist/`, and at the same depth, so the map's relative sources still resolve.
|
|
139
|
-
*/
|
|
140
108
|
async function watchMain(state) {
|
|
141
109
|
const vite = await loadVite(state.pkg);
|
|
142
110
|
const staging = path.join(state.pkg, ".drift-beacon/main-next");
|
|
143
111
|
const options = { outDir: staging, minify: false, sourcemap: true, watch: {}, logLevel: "silent" };
|
|
144
112
|
const watcher = (await vite.build(mainBuild(vite, state.pkg, options)));
|
|
145
|
-
// Vite closes each event's bundle itself.
|
|
146
113
|
watcher.on("event", (event) => {
|
|
147
114
|
if (event.code === "BUNDLE_END") {
|
|
148
115
|
try {
|
|
@@ -158,7 +125,6 @@ async function watchMain(state) {
|
|
|
158
125
|
}
|
|
159
126
|
}
|
|
160
127
|
else if (event.code === "ERROR") {
|
|
161
|
-
// dist/ is untouched, so the server keeps the last good build.
|
|
162
128
|
const reason = shorten(state, event.error.message).replaceAll(/\n\s*\n/g, "\n");
|
|
163
129
|
print(state.logger, {
|
|
164
130
|
level: "error",
|
|
@@ -168,13 +134,11 @@ async function watchMain(state) {
|
|
|
168
134
|
});
|
|
169
135
|
return watcher;
|
|
170
136
|
}
|
|
171
|
-
/** Per dev server: the manifest and icon watchers, the marker, and the server's socket. */
|
|
172
137
|
function serveDev(server, state) {
|
|
173
138
|
state.servers += 1;
|
|
174
139
|
state.logger = server.config.logger;
|
|
175
140
|
const manifestFile = path.join(state.pkg, "manifest.json");
|
|
176
141
|
server.watcher.add(manifestFile);
|
|
177
|
-
// Vite already watches its root `ui/`, so the icon's changes arrive here too.
|
|
178
142
|
server.watcher.on("all", (event, file) => {
|
|
179
143
|
if (file === manifestFile && event !== "unlink")
|
|
180
144
|
updateManifest(state);
|
|
@@ -183,7 +147,6 @@ function serveDev(server, state) {
|
|
|
183
147
|
});
|
|
184
148
|
server.httpServer?.on("listening", () => {
|
|
185
149
|
state.uiUrl = server.resolvedUrls?.local[0] ?? null;
|
|
186
|
-
// Even before main has built: the server can connect and serve the UI meanwhile.
|
|
187
150
|
writeDevMarker(state);
|
|
188
151
|
clearTimeout(state.hint);
|
|
189
152
|
state.hint = setTimeout(() => {
|
|
@@ -191,7 +154,6 @@ function serveDev(server, state) {
|
|
|
191
154
|
print(state.logger, { level: "warn", text: noServerHint(state) });
|
|
192
155
|
}, HINT_DELAY_MS).unref();
|
|
193
156
|
});
|
|
194
|
-
// On the dev server's own close: its http server emits "close" only if it listened, and has none in middleware mode.
|
|
195
157
|
const close = server.close.bind(server);
|
|
196
158
|
let open = true;
|
|
197
159
|
server.close = () => {
|
|
@@ -201,12 +163,11 @@ function serveDev(server, state) {
|
|
|
201
163
|
}
|
|
202
164
|
return close();
|
|
203
165
|
};
|
|
204
|
-
// Vite custom events over the HMR socket. Never `server.ws.send`: it broadcasts, plugin iframes included.
|
|
205
166
|
server.ws.on("drift-beacon:hello", (data, client) => {
|
|
206
167
|
if (data?.session !== state.session)
|
|
207
168
|
return;
|
|
208
169
|
const welcome = { v: 1, session: state.session, pluginId: state.manifest.id };
|
|
209
|
-
client.send("drift-beacon:welcome", welcome);
|
|
170
|
+
client.send("drift-beacon:welcome", welcome);
|
|
210
171
|
clearTimeout(state.hint);
|
|
211
172
|
const { socket } = client;
|
|
212
173
|
state.socket = socket;
|
|
@@ -222,7 +183,6 @@ function serveDev(server, state) {
|
|
|
222
183
|
print(state.logger, data);
|
|
223
184
|
});
|
|
224
185
|
}
|
|
225
|
-
/** One dev server closed: the last one for the root stops the main watch build and forgets the root. */
|
|
226
186
|
function release(state) {
|
|
227
187
|
if (--state.servers > 0)
|
|
228
188
|
return;
|
|
@@ -231,16 +191,13 @@ function release(state) {
|
|
|
231
191
|
devStates.delete(state.pkg);
|
|
232
192
|
void state.watcher.then((watcher) => watcher?.close());
|
|
233
193
|
}
|
|
234
|
-
/** A saved manifest: checked, copied, and its config types and icon refreshed. An invalid one keeps the old copy. */
|
|
235
194
|
function updateManifest(state) {
|
|
236
195
|
try {
|
|
237
196
|
const { manifest, bytes } = prepare(state.pkg, { strict: true });
|
|
238
|
-
// A missing icon was already reported under its name; say it again only for a new name.
|
|
239
197
|
const renamed = manifest.icon !== state.manifest.icon;
|
|
240
198
|
state.manifest = manifest;
|
|
241
199
|
state.manifestBytes = bytes;
|
|
242
200
|
syncIcon(state, renamed);
|
|
243
|
-
// Copies the manifest.
|
|
244
201
|
writeDevMarker(state);
|
|
245
202
|
}
|
|
246
203
|
catch (error) {
|
|
@@ -250,7 +207,6 @@ function updateManifest(state) {
|
|
|
250
207
|
});
|
|
251
208
|
}
|
|
252
209
|
}
|
|
253
|
-
/** Copies the manifest icon from `ui/public/` into `dist/ui/` (Vite does it in a build), or removes a deleted one. */
|
|
254
210
|
function syncIcon(state, warnMissing) {
|
|
255
211
|
const { icon } = state.manifest;
|
|
256
212
|
if (!icon)
|
|
@@ -275,7 +231,6 @@ function syncIcon(state, warnMissing) {
|
|
|
275
231
|
});
|
|
276
232
|
}
|
|
277
233
|
}
|
|
278
|
-
/** Moves every staged file into `to`, maps first and `index.js` last, so the new index.js never meets an old map. */
|
|
279
234
|
function moveFiles(from, to) {
|
|
280
235
|
const rank = (file) => (file === "index.js" ? 2 : file.endsWith(".map") ? 0 : 1);
|
|
281
236
|
const files = readdirSync(from, { recursive: true, withFileTypes: true })
|
|
@@ -287,10 +242,6 @@ function moveFiles(from, to) {
|
|
|
287
242
|
renameSync(path.join(from, file), path.join(to, file));
|
|
288
243
|
}
|
|
289
244
|
}
|
|
290
|
-
/**
|
|
291
|
-
* Writes the dev marker for what is in `dist/` now; true when its build id changed. The manifest, `package.json`
|
|
292
|
-
* and a missing icon are written first, so a `dist/` deleted while `pnpm dev` runs is whole again.
|
|
293
|
-
*/
|
|
294
245
|
function writeDevMarker(state) {
|
|
295
246
|
writeAtomic(path.join(state.dist, "manifest.json"), state.manifestBytes);
|
|
296
247
|
writeAtomic(path.join(state.dist, "package.json"), `${JSON.stringify(PACKAGE_JSON, null, 2)}\n`);
|
|
@@ -307,7 +258,6 @@ const noServerHint = (state) => [
|
|
|
307
258
|
`The server connects when it finds dist/${DEV_MARKER} in a folder directly`,
|
|
308
259
|
`under its DEV_PLUGINS_PATH. Run it in development mode with DEV_PLUGINS_PATH=${path.dirname(state.pkg)}`,
|
|
309
260
|
].join("\n");
|
|
310
|
-
/** Plain text with package paths made relative, for messages that come from Vite or the file system. */
|
|
311
261
|
const shorten = (state, text) => stripVTControlCharacters(text).replaceAll(`${state.pkg}${path.sep}`, "").trim();
|
|
312
262
|
const TIME = new Intl.DateTimeFormat(undefined, { hour: "numeric", minute: "numeric", second: "numeric" });
|
|
313
263
|
const STYLES = {
|
|
@@ -316,11 +266,6 @@ const STYLES = {
|
|
|
316
266
|
warn: "yellow",
|
|
317
267
|
error: "red",
|
|
318
268
|
};
|
|
319
|
-
/**
|
|
320
|
-
* Prints a line (from the server, or about the local build) through Vite's logger, timed like Vite's own lines
|
|
321
|
-
* but tagged `[beacon]` (Vite's `timestamp` option would tag it `[vite]`). The first line is coloured by level;
|
|
322
|
-
* the others are dimmed and indented under it.
|
|
323
|
-
*/
|
|
324
269
|
function print(logger, { level, text }) {
|
|
325
270
|
const time = TIME.format(new Date());
|
|
326
271
|
const [first = "", ...rest] = String(text).split("\n");
|
|
@@ -336,21 +281,12 @@ function print(logger, { level, text }) {
|
|
|
336
281
|
else
|
|
337
282
|
logger.info(message);
|
|
338
283
|
}
|
|
339
|
-
// ============================================================================
|
|
340
|
-
// Shared
|
|
341
|
-
// ============================================================================
|
|
342
|
-
/** Writes the marker for what is in `dist/` now and returns its build id. */
|
|
343
284
|
function writeMarker(dist, { pluginId, session, uiUrl }) {
|
|
344
285
|
const buildId = hashDist(dist);
|
|
345
|
-
// The HMR socket shares the UI's host and port; a relative base serves it at `/`.
|
|
346
286
|
const marker = { v: 1, pluginId, buildId, session, uiUrl, wsUrl: uiUrl?.replace(/^http/, "ws") ?? null };
|
|
347
287
|
writeAtomic(path.join(dist, DEV_MARKER), `${JSON.stringify(marker, null, 2)}\n`);
|
|
348
288
|
return buildId;
|
|
349
289
|
}
|
|
350
|
-
/**
|
|
351
|
-
* The build id: sha256 of what the server loads, first 16 hex characters. Null until main is built. It
|
|
352
|
-
* covers `ui/index.html` so a UI-only build still refreshes an open static UI.
|
|
353
|
-
*/
|
|
354
290
|
function hashDist(dist) {
|
|
355
291
|
if (!existsSync(path.join(dist, "main/index.js")))
|
|
356
292
|
return null;
|
|
@@ -362,7 +298,6 @@ function hashDist(dist) {
|
|
|
362
298
|
}
|
|
363
299
|
return hash.digest("hex").slice(0, 16);
|
|
364
300
|
}
|
|
365
|
-
/** Writes through a temporary file and a rename, so the server never reads a partial file. */
|
|
366
301
|
function writeAtomic(file, content) {
|
|
367
302
|
mkdirSync(path.dirname(file), { recursive: true });
|
|
368
303
|
writeFileSync(`${file}.tmp`, content);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drift-beacon/plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "The Drift Beacon plugin SDK: APIs for plugin main code and UIs, the driftBeacon() Vite plugin and the dbplugin CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -38,8 +38,15 @@
|
|
|
38
38
|
},
|
|
39
39
|
"files": [
|
|
40
40
|
"bin",
|
|
41
|
-
"dist",
|
|
42
|
-
"!dist
|
|
41
|
+
"dist/**/*.js",
|
|
42
|
+
"!dist/internal.js",
|
|
43
|
+
"dist/index.d.ts",
|
|
44
|
+
"dist/ui.d.ts",
|
|
45
|
+
"dist/vite.d.ts",
|
|
46
|
+
"dist/main.d.ts",
|
|
47
|
+
"dist/types.d.ts",
|
|
48
|
+
"dist/errors.d.ts",
|
|
49
|
+
"dist/version.d.ts"
|
|
43
50
|
],
|
|
44
51
|
"publishConfig": {
|
|
45
52
|
"access": "public"
|
|
@@ -65,7 +72,7 @@
|
|
|
65
72
|
"vite": "7.1.2"
|
|
66
73
|
},
|
|
67
74
|
"scripts": {
|
|
68
|
-
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
75
|
+
"build": "rm -rf dist && tsc -p tsconfig.json --removeComments && tsc -p tsconfig.json --emitDeclarationOnly",
|
|
69
76
|
"clean": "rm -rf dist",
|
|
70
77
|
"typecheck": "tsc --noEmit && node scripts/api-report.mjs --check",
|
|
71
78
|
"api:update": "node scripts/api-report.mjs"
|
package/dist/cli.d.ts
DELETED
package/dist/dev.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The `pnpm dev` handshake between `driftBeacon()` and the Drift Beacon server. The dev tool writes a
|
|
3
|
-
* marker into the package's `dist/`; the server polls for it, connects to Vite's HMR socket and trusts
|
|
4
|
-
* the socket only after a `welcome` whose `session` equals the marker's. Messages travel as Vite custom
|
|
5
|
-
* events (`{ type: "custom", event, data }`). All wording is rendered on the server; the tool only prints.
|
|
6
|
-
*/
|
|
7
|
-
/** File name of the marker in `dist/`. Written as tmp, then renamed, synchronously. Never packed. */
|
|
8
|
-
export declare const DEV_MARKER = ".drift-beacon-dev.json";
|
|
9
|
-
export interface DevMarker {
|
|
10
|
-
readonly v: 1;
|
|
11
|
-
/** `manifest.id`; the server routes logs and the dev UI URL by it. */
|
|
12
|
-
readonly pluginId: string;
|
|
13
|
-
/** Hash of the built package; null until `dist/main/index.js` exists. A new id means a new build. */
|
|
14
|
-
readonly buildId: string | null;
|
|
15
|
-
/** One per `pnpm dev` process and package root; null after `vite build`. */
|
|
16
|
-
readonly session: string | null;
|
|
17
|
-
/** The dev server's UI URL, for example `http://localhost:5174/`. */
|
|
18
|
-
readonly uiUrl: string | null;
|
|
19
|
-
/** The dev server's HMR socket, for example `ws://localhost:5174/`. */
|
|
20
|
-
readonly wsUrl: string | null;
|
|
21
|
-
}
|
|
22
|
-
/** Server → tool, event `drift-beacon:hello`. */
|
|
23
|
-
export interface DevHello {
|
|
24
|
-
readonly v: 1;
|
|
25
|
-
readonly session: string;
|
|
26
|
-
}
|
|
27
|
-
/** Tool → server, event `drift-beacon:welcome`, sent only to the socket that said hello. */
|
|
28
|
-
export interface DevWelcome {
|
|
29
|
-
readonly v: 1;
|
|
30
|
-
readonly session: string;
|
|
31
|
-
readonly pluginId: string;
|
|
32
|
-
}
|
|
33
|
-
/** Server → tool, event `drift-beacon:print`: one line (or block) for the plugin's terminal. */
|
|
34
|
-
export interface DevPrint {
|
|
35
|
-
readonly level: "info" | "success" | "warn" | "error";
|
|
36
|
-
readonly text: string;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=dev.d.ts.map
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Requests an instance's main code sends to the server through its plugin host. The server runs them
|
|
3
|
-
* as the instance's user in the instance's workspace.
|
|
4
|
-
*/
|
|
5
|
-
export type PluginAction = {
|
|
6
|
-
readonly name: "startSession";
|
|
7
|
-
readonly activityId: string;
|
|
8
|
-
} | {
|
|
9
|
-
readonly name: "endSession";
|
|
10
|
-
readonly sessionId: string;
|
|
11
|
-
} | {
|
|
12
|
-
readonly name: "markPoint";
|
|
13
|
-
readonly activityId: string;
|
|
14
|
-
} | {
|
|
15
|
-
readonly name: "discardSession";
|
|
16
|
-
readonly sessionId: string;
|
|
17
|
-
} | {
|
|
18
|
-
readonly name: "storageSet";
|
|
19
|
-
readonly key: string;
|
|
20
|
-
readonly value: unknown;
|
|
21
|
-
} | {
|
|
22
|
-
readonly name: "storageRemove";
|
|
23
|
-
readonly key: string;
|
|
24
|
-
} | {
|
|
25
|
-
readonly name: "mqttSubscribe";
|
|
26
|
-
readonly topic: string;
|
|
27
|
-
} | {
|
|
28
|
-
readonly name: "mqttUnsubscribe";
|
|
29
|
-
readonly topic: string;
|
|
30
|
-
} | {
|
|
31
|
-
readonly name: "mqttPublish";
|
|
32
|
-
readonly topic: string;
|
|
33
|
-
readonly payload: string;
|
|
34
|
-
};
|
|
35
|
-
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { RowChange } from "./rows.ts";
|
|
2
|
-
/**
|
|
3
|
-
* A collection of plain rows keyed by id, frozen as they arrive. `replace` applies a full set of rows, keeps the
|
|
4
|
-
* object of every unchanged row (so identity only changes when data does) and reports the changes.
|
|
5
|
-
*/
|
|
6
|
-
export declare class Collection<T extends {
|
|
7
|
-
readonly id: string;
|
|
8
|
-
}> {
|
|
9
|
-
private rows;
|
|
10
|
-
private cachedList;
|
|
11
|
-
list(): readonly T[];
|
|
12
|
-
get(id: string): T | undefined;
|
|
13
|
-
replace(incoming: readonly T[]): RowChange<T>[];
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=collection.d.ts.map
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API versions this build of Drift Beacon runs: the newest minor of each supported major.
|
|
3
|
-
* Before 1.0 only the current version is listed, because every 0.x minor may break plugins.
|
|
4
|
-
* From 1.0, the previous major stays listed for at least six months after its successor ships.
|
|
5
|
-
*/
|
|
6
|
-
export declare const SUPPORTED_API_VERSIONS: readonly string[];
|
|
7
|
-
export interface ApiVersion {
|
|
8
|
-
readonly major: number;
|
|
9
|
-
readonly minor: number;
|
|
10
|
-
}
|
|
11
|
-
/** Parse a `major.minor` API version; null when malformed. */
|
|
12
|
-
export declare function parseApiVersion(value: unknown): ApiVersion | null;
|
|
13
|
-
export type ApiCompatibility = {
|
|
14
|
-
readonly compatible: true;
|
|
15
|
-
} | {
|
|
16
|
-
readonly compatible: false;
|
|
17
|
-
readonly reason: "invalid" | "needs-newer-app" | "needs-plugin-update";
|
|
18
|
-
readonly message: string;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Whether a plugin built for `pluginVersion` runs on a build supporting `supported`.
|
|
22
|
-
* Before 1.0 the minor must match exactly; from 1.0 the major must match and the plugin's
|
|
23
|
-
* minor must not be newer than the host's.
|
|
24
|
-
*/
|
|
25
|
-
export declare function checkApiCompatibility(pluginVersion: unknown, supported?: readonly string[]): ApiCompatibility;
|
|
26
|
-
//# sourceMappingURL=compatibility.d.ts.map
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
interface ConfigurationItemBase {
|
|
2
|
-
name: string;
|
|
3
|
-
title: string;
|
|
4
|
-
description?: string;
|
|
5
|
-
required?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export interface StringConfigurationItem extends ConfigurationItemBase {
|
|
8
|
-
type: "string";
|
|
9
|
-
default?: string;
|
|
10
|
-
placeholder?: string;
|
|
11
|
-
}
|
|
12
|
-
export interface NumberConfigurationItem extends ConfigurationItemBase {
|
|
13
|
-
type: "number";
|
|
14
|
-
default?: number;
|
|
15
|
-
minimum?: number;
|
|
16
|
-
maximum?: number;
|
|
17
|
-
}
|
|
18
|
-
export interface BooleanConfigurationItem extends ConfigurationItemBase {
|
|
19
|
-
type: "boolean";
|
|
20
|
-
default?: boolean;
|
|
21
|
-
}
|
|
22
|
-
export interface DropdownConfigurationItem extends ConfigurationItemBase {
|
|
23
|
-
type: "dropdown";
|
|
24
|
-
default?: string;
|
|
25
|
-
data: ReadonlyArray<{
|
|
26
|
-
readonly title: string;
|
|
27
|
-
readonly value: string;
|
|
28
|
-
}>;
|
|
29
|
-
}
|
|
30
|
-
/** One setting declared in `manifest.json`; drives the settings form and config validation. */
|
|
31
|
-
export type ConfigurationItem = StringConfigurationItem | NumberConfigurationItem | BooleanConfigurationItem | DropdownConfigurationItem;
|
|
32
|
-
export interface PluginManifest {
|
|
33
|
-
id: string;
|
|
34
|
-
name: string;
|
|
35
|
-
version: string;
|
|
36
|
-
/** Plugin API version (`major.minor`) the plugin was built for. */
|
|
37
|
-
apiVersion: string;
|
|
38
|
-
description: string;
|
|
39
|
-
author: {
|
|
40
|
-
name: string;
|
|
41
|
-
email?: string;
|
|
42
|
-
};
|
|
43
|
-
category: "plugin" | "utility" | "ui";
|
|
44
|
-
icon: string;
|
|
45
|
-
configuration: readonly ConfigurationItem[];
|
|
46
|
-
}
|
|
47
|
-
export declare const isStableVersion: (value: unknown) => value is string;
|
|
48
|
-
/** Throws a readable error when `manifest` is not a valid plugin manifest. Shared by the server and the pack tool. */
|
|
49
|
-
export declare function validateManifest(manifest: unknown): asserts manifest is PluginManifest;
|
|
50
|
-
export {};
|
|
51
|
-
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import type { ActivitiesApi, Activity, ActivityFilter, CategoriesApi, Category, Change, Session, SessionData, SessionFilter, SessionsApi } from "../types.ts";
|
|
2
|
-
import type { Collection } from "./collection.ts";
|
|
3
|
-
import type { ActivityRow, CategoryRow, SessionRow, WorkspaceRowChanges } from "./rows.ts";
|
|
4
|
-
export interface WorkspaceCollections {
|
|
5
|
-
readonly activities: Collection<ActivityRow>;
|
|
6
|
-
readonly categories: Collection<CategoryRow>;
|
|
7
|
-
readonly sessions: Collection<SessionRow>;
|
|
8
|
-
}
|
|
9
|
-
/** Session operations. Each resolves with the session's row once the snapshot containing the result has arrived. */
|
|
10
|
-
export interface SessionActions {
|
|
11
|
-
start(activityId: string): Promise<unknown>;
|
|
12
|
-
end(sessionId: string): Promise<unknown>;
|
|
13
|
-
mark(activityId: string): Promise<unknown>;
|
|
14
|
-
discard(sessionId: string): Promise<unknown>;
|
|
15
|
-
}
|
|
16
|
-
export interface ModelChanges {
|
|
17
|
-
readonly activities: readonly Change<Activity>[];
|
|
18
|
-
readonly categories: readonly Change<Category>[];
|
|
19
|
-
readonly sessions: readonly Change<Session>[];
|
|
20
|
-
}
|
|
21
|
-
/** The reads and actions of `ctx.activities`, `ctx.categories` and `ctx.sessions`. Contexts add the events. */
|
|
22
|
-
export interface ModelApis {
|
|
23
|
-
readonly activities: Omit<ActivitiesApi, "onChange">;
|
|
24
|
-
readonly categories: Omit<CategoriesApi, "onChange">;
|
|
25
|
-
readonly sessions: Omit<SessionsApi, "onChange">;
|
|
26
|
-
}
|
|
27
|
-
export declare class WorkspaceModels {
|
|
28
|
-
#private;
|
|
29
|
-
readonly userId: string;
|
|
30
|
-
readonly rows: WorkspaceCollections;
|
|
31
|
-
constructor(options: {
|
|
32
|
-
readonly userId: string;
|
|
33
|
-
readonly rows: WorkspaceCollections;
|
|
34
|
-
readonly actions: SessionActions;
|
|
35
|
-
});
|
|
36
|
-
/** The reads and actions for `ctx`. */
|
|
37
|
-
apis(): ModelApis;
|
|
38
|
-
activity(id: string): Activity | undefined;
|
|
39
|
-
category(id: string): Category | undefined;
|
|
40
|
-
session(id: string): Session | undefined;
|
|
41
|
-
/** In the app's order: by category (uncategorized last), then `sortOrder`, then name. */
|
|
42
|
-
activities(filter?: ActivityFilter): readonly Activity[];
|
|
43
|
-
/** By `sortOrder`, then name. */
|
|
44
|
-
categories(): readonly Category[];
|
|
45
|
-
/** Newest first. */
|
|
46
|
-
sessions(filter?: SessionFilter): readonly Session[];
|
|
47
|
-
start(activityId: string): Promise<Session>;
|
|
48
|
-
end(sessionId: string): Promise<Session>;
|
|
49
|
-
mark(activityId: string): Promise<Session>;
|
|
50
|
-
discard(sessionId: string): Promise<void>;
|
|
51
|
-
/** Turn the row changes of a snapshot into model changes. Call it after the collections were replaced. */
|
|
52
|
-
update(changes: WorkspaceRowChanges): ModelChanges;
|
|
53
|
-
/**
|
|
54
|
-
* The model for a session the app sent outside a snapshot (a live event or an action result):
|
|
55
|
-
* the snapshot's model, or, when the row isn't in the snapshot, a removed model holding these values.
|
|
56
|
-
*/
|
|
57
|
-
sessionFrom(row: SessionRow): Session;
|
|
58
|
-
activityRow(id: string): ActivityRow;
|
|
59
|
-
categoryRow(id: string): CategoryRow;
|
|
60
|
-
sessionData(id: string): SessionData;
|
|
61
|
-
}
|
|
62
|
-
//# sourceMappingURL=models.d.ts.map
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The plugin package: `manifest.json`, `package.json`, `main/index.js` (plus chunks) and `ui/index.html`
|
|
3
|
-
* (plus assets and the manifest icon). Shared by the pack tool and the server. Pure: the web app bundles
|
|
4
|
-
* `/internal`, so no `node:` imports.
|
|
5
|
-
*/
|
|
6
|
-
export declare const PACKAGE_LIMITS: {
|
|
7
|
-
readonly entries: 2000;
|
|
8
|
-
readonly fileBytes: number;
|
|
9
|
-
readonly totalBytes: number;
|
|
10
|
-
readonly archiveBytes: number;
|
|
11
|
-
readonly manifestBytes: number;
|
|
12
|
-
};
|
|
13
|
-
/** The `package.json` every package gets: main is ESM. */
|
|
14
|
-
export declare const PACKAGE_JSON: {
|
|
15
|
-
readonly type: "module";
|
|
16
|
-
readonly private: true;
|
|
17
|
-
};
|
|
18
|
-
export declare const REQUIRED_FILES: readonly ["main/index.js", "ui/index.html"];
|
|
19
|
-
/** manifest.json, package.json, main/** and ui/** (directories: main, ui and below). `name` has no trailing slash. */
|
|
20
|
-
export declare const isPackagePath: (name: string, directory: boolean) => boolean;
|
|
21
|
-
//# sourceMappingURL=package-layout.d.ts.map
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Messages between a plugin UI (iframe) and the web app hosting it, over `postMessage`.
|
|
3
|
-
*
|
|
4
|
-
* The UI client ships inside every published UI bundle, so this protocol is frozen into
|
|
5
|
-
* them: change it only additively within an API version. The UI opens with `hello`; nothing
|
|
6
|
-
* else flows until the host answers `welcome` or `reject`.
|
|
7
|
-
*/
|
|
8
|
-
import type { PluginErrorCode, PluginInfo, UserInfo, WorkspaceInfo } from "../types.ts";
|
|
9
|
-
import type { WorkspaceRows } from "./rows.ts";
|
|
10
|
-
/** Marks our messages so both sides ignore unrelated `postMessage` traffic (dev tools, HMR). */
|
|
11
|
-
export declare const UI_CHANNEL = "drift-beacon-plugin";
|
|
12
|
-
/** Workspace data sent to a UI, as rows. */
|
|
13
|
-
export type UiData = WorkspaceRows;
|
|
14
|
-
export type UiRequest = {
|
|
15
|
-
readonly method: "sessions.start";
|
|
16
|
-
readonly params: {
|
|
17
|
-
readonly activityId: string;
|
|
18
|
-
};
|
|
19
|
-
} | {
|
|
20
|
-
readonly method: "sessions.end";
|
|
21
|
-
readonly params: {
|
|
22
|
-
readonly sessionId: string;
|
|
23
|
-
};
|
|
24
|
-
} | {
|
|
25
|
-
readonly method: "sessions.mark";
|
|
26
|
-
readonly params: {
|
|
27
|
-
readonly activityId: string;
|
|
28
|
-
};
|
|
29
|
-
} | {
|
|
30
|
-
readonly method: "sessions.discard";
|
|
31
|
-
readonly params: {
|
|
32
|
-
readonly sessionId: string;
|
|
33
|
-
};
|
|
34
|
-
} | {
|
|
35
|
-
readonly method: "storage.set";
|
|
36
|
-
readonly params: {
|
|
37
|
-
readonly key: string;
|
|
38
|
-
readonly value: unknown;
|
|
39
|
-
};
|
|
40
|
-
} | {
|
|
41
|
-
readonly method: "storage.remove";
|
|
42
|
-
readonly params: {
|
|
43
|
-
readonly key: string;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
export type UiToHostMessage = {
|
|
47
|
-
readonly channel: typeof UI_CHANNEL;
|
|
48
|
-
readonly type: "hello";
|
|
49
|
-
readonly apiVersion: string;
|
|
50
|
-
} | ({
|
|
51
|
-
readonly channel: typeof UI_CHANNEL;
|
|
52
|
-
readonly type: "request";
|
|
53
|
-
readonly id: string;
|
|
54
|
-
} & UiRequest);
|
|
55
|
-
export interface UiError {
|
|
56
|
-
readonly code: PluginErrorCode;
|
|
57
|
-
readonly message: string;
|
|
58
|
-
}
|
|
59
|
-
export type HostToUiMessage = {
|
|
60
|
-
readonly channel: typeof UI_CHANNEL;
|
|
61
|
-
readonly type: "welcome";
|
|
62
|
-
readonly apiVersion: string;
|
|
63
|
-
readonly plugin: PluginInfo;
|
|
64
|
-
readonly user: UserInfo;
|
|
65
|
-
readonly workspace: WorkspaceInfo;
|
|
66
|
-
readonly config: Readonly<Record<string, unknown>>;
|
|
67
|
-
readonly data: UiData;
|
|
68
|
-
readonly storage: Readonly<Record<string, unknown>>;
|
|
69
|
-
} | {
|
|
70
|
-
readonly channel: typeof UI_CHANNEL;
|
|
71
|
-
readonly type: "reject";
|
|
72
|
-
readonly reason: string;
|
|
73
|
-
}
|
|
74
|
-
/** The app restarted its side of the connection; the UI answers with `hello` and gets a new `welcome`. */
|
|
75
|
-
| {
|
|
76
|
-
readonly channel: typeof UI_CHANNEL;
|
|
77
|
-
readonly type: "reconnect";
|
|
78
|
-
} | {
|
|
79
|
-
/** Replaces whichever parts are present. */
|
|
80
|
-
readonly channel: typeof UI_CHANNEL;
|
|
81
|
-
readonly type: "state";
|
|
82
|
-
readonly config?: Readonly<Record<string, unknown>>;
|
|
83
|
-
readonly data?: UiData;
|
|
84
|
-
readonly storage?: Readonly<Record<string, unknown>>;
|
|
85
|
-
} | {
|
|
86
|
-
readonly channel: typeof UI_CHANNEL;
|
|
87
|
-
readonly type: "response";
|
|
88
|
-
readonly id: string;
|
|
89
|
-
readonly result?: unknown;
|
|
90
|
-
readonly error?: UiError;
|
|
91
|
-
};
|
|
92
|
-
export declare function isUiMessage(value: unknown): value is {
|
|
93
|
-
channel: typeof UI_CHANNEL;
|
|
94
|
-
type: string;
|
|
95
|
-
};
|
|
96
|
-
//# sourceMappingURL=protocol.d.ts.map
|
package/dist/internal/rows.d.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workspace data as it travels from the app to plugins: to plugin hosts over IPC and to plugin
|
|
3
|
-
* UIs over `postMessage`. Plugins never see rows; the model layer (`models.ts`) wraps them.
|
|
4
|
-
*/
|
|
5
|
-
import type { ActivityData, CategoryData } from "../types.ts";
|
|
6
|
-
export type ActivityRow = ActivityData;
|
|
7
|
-
export type CategoryRow = CategoryData;
|
|
8
|
-
export interface SessionRow {
|
|
9
|
-
readonly id: string;
|
|
10
|
-
readonly activityId: string;
|
|
11
|
-
readonly type: "span" | "point";
|
|
12
|
-
readonly status: "live" | "completed";
|
|
13
|
-
readonly memberIds: readonly string[];
|
|
14
|
-
/** ISO timestamp: when a span started, or when a point was marked. */
|
|
15
|
-
readonly startedAt: string;
|
|
16
|
-
/** ISO timestamp when a span ended; null while live and for points. */
|
|
17
|
-
readonly endedAt: string | null;
|
|
18
|
-
}
|
|
19
|
-
export interface WorkspaceRows {
|
|
20
|
-
readonly activities: readonly ActivityRow[];
|
|
21
|
-
readonly categories: readonly CategoryRow[];
|
|
22
|
-
readonly sessions: readonly SessionRow[];
|
|
23
|
-
}
|
|
24
|
-
/** One change to a collection of rows. */
|
|
25
|
-
export type RowChange<T> = {
|
|
26
|
-
readonly type: "added";
|
|
27
|
-
readonly item: T;
|
|
28
|
-
} | {
|
|
29
|
-
readonly type: "updated";
|
|
30
|
-
readonly item: T;
|
|
31
|
-
readonly previous: T;
|
|
32
|
-
} | {
|
|
33
|
-
readonly type: "removed";
|
|
34
|
-
readonly item: T;
|
|
35
|
-
};
|
|
36
|
-
export interface WorkspaceRowChanges {
|
|
37
|
-
readonly activities: readonly RowChange<ActivityRow>[];
|
|
38
|
-
readonly categories: readonly RowChange<CategoryRow>[];
|
|
39
|
-
readonly sessions: readonly RowChange<SessionRow>[];
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=rows.d.ts.map
|
package/dist/internal.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Platform-only entry used by the plugin host, the web app and the server. Not part of the plugin API.
|
|
3
|
-
* Public entries never import this file; SDK modules may import `internal/*` directly. Publishing drops
|
|
4
|
-
* only its export key.
|
|
5
|
-
*/
|
|
6
|
-
export * from "./dev.ts";
|
|
7
|
-
export type { PluginAction } from "./internal/actions.ts";
|
|
8
|
-
export { Collection } from "./internal/collection.ts";
|
|
9
|
-
export { type ApiCompatibility, type ApiVersion, checkApiCompatibility, parseApiVersion, SUPPORTED_API_VERSIONS, } from "./internal/compatibility.ts";
|
|
10
|
-
export { jsonEqual } from "./internal/json-equal.ts";
|
|
11
|
-
export { type BooleanConfigurationItem, type ConfigurationItem, type DropdownConfigurationItem, isStableVersion, type NumberConfigurationItem, type PluginManifest, type StringConfigurationItem, validateManifest, } from "./internal/manifest.ts";
|
|
12
|
-
export { type ModelApis, type ModelChanges, type SessionActions, type WorkspaceCollections, WorkspaceModels, } from "./internal/models.ts";
|
|
13
|
-
export { isPackagePath, PACKAGE_JSON, PACKAGE_LIMITS, REQUIRED_FILES } from "./internal/package-layout.ts";
|
|
14
|
-
export * from "./internal/protocol.ts";
|
|
15
|
-
export type { ActivityRow, CategoryRow, RowChange, SessionRow, WorkspaceRowChanges, WorkspaceRows, } from "./internal/rows.ts";
|
|
16
|
-
export type { PluginErrorCode } from "./types.ts";
|
|
17
|
-
//# sourceMappingURL=internal.d.ts.map
|
package/dist/internal.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Platform-only entry used by the plugin host, the web app and the server. Not part of the plugin API.
|
|
3
|
-
* Public entries never import this file; SDK modules may import `internal/*` directly. Publishing drops
|
|
4
|
-
* only its export key.
|
|
5
|
-
*/
|
|
6
|
-
export * from "./dev.js";
|
|
7
|
-
export { Collection } from "./internal/collection.js";
|
|
8
|
-
export { checkApiCompatibility, parseApiVersion, SUPPORTED_API_VERSIONS, } from "./internal/compatibility.js";
|
|
9
|
-
export { jsonEqual } from "./internal/json-equal.js";
|
|
10
|
-
export { isStableVersion, validateManifest, } from "./internal/manifest.js";
|
|
11
|
-
export { WorkspaceModels, } from "./internal/models.js";
|
|
12
|
-
export { isPackagePath, PACKAGE_JSON, PACKAGE_LIMITS, REQUIRED_FILES } from "./internal/package-layout.js";
|
|
13
|
-
export * from "./internal/protocol.js";
|
package/dist/pack.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export interface PackResult {
|
|
2
|
-
readonly id: string;
|
|
3
|
-
readonly version: string;
|
|
4
|
-
readonly tag: string;
|
|
5
|
-
readonly asset: string;
|
|
6
|
-
readonly archivePath: string;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Zip the package in `dir` into `<outDir>/<id>.zip`: its manifest, a generated `package.json`, and `main/**`
|
|
10
|
-
* and `ui/**`. Anything else in `dir` (the dev marker, its `package.json`) is left out. Never runs plugin code.
|
|
11
|
-
*/
|
|
12
|
-
export declare function packDirectory(dir: string, outDir: string): Promise<PackResult>;
|
|
13
|
-
export interface PackOptions {
|
|
14
|
-
/** Where the zip goes. Default `<root>/releases`. */
|
|
15
|
-
readonly out?: string;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Build a release of the plugin package at `root`: prepare, typecheck main and UI with the package's own
|
|
19
|
-
* TypeScript, `vite build` into a fresh temp folder with the package's own Vite, then `packDirectory`. The
|
|
20
|
-
* package's `dist/` is never read or written. Everything printed meanwhile goes to stderr, so a caller's
|
|
21
|
-
* stdout carries only the result.
|
|
22
|
-
*/
|
|
23
|
-
export declare function pack(root: string, options?: PackOptions): Promise<PackResult>;
|
|
24
|
-
//# sourceMappingURL=pack.d.ts.map
|
package/dist/prepare.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { type PluginManifest } from "./internal/manifest.ts";
|
|
2
|
-
export interface PrepareOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Throw on manifest problems (dev, build and pack). When false (`dbplugin prepare`, run on install), warn
|
|
5
|
-
* and leave `.drift-beacon/` as it was, so a manifest typo never fails `pnpm install`.
|
|
6
|
-
*/
|
|
7
|
-
readonly strict: boolean;
|
|
8
|
-
}
|
|
9
|
-
/** A package's `manifest.json`: parsed and checked, with its bytes. */
|
|
10
|
-
export interface LoadedManifest {
|
|
11
|
-
readonly manifest: PluginManifest;
|
|
12
|
-
readonly bytes: Buffer;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Generate `<root>/.drift-beacon/` from the manifest, and return the manifest (`loadManifest`). Files are
|
|
16
|
-
* rewritten only when their content changes.
|
|
17
|
-
*/
|
|
18
|
-
export declare function prepare(root: string, options: {
|
|
19
|
-
readonly strict: true;
|
|
20
|
-
}): LoadedManifest;
|
|
21
|
-
export declare function prepare(root: string, options: PrepareOptions): LoadedManifest | null;
|
|
22
|
-
/**
|
|
23
|
-
* `<root>/manifest.json`, the one read of a manifest in the SDK (dev, build, prepare and pack): a regular
|
|
24
|
-
* file within the package limit, valid, and for an `apiVersion` this SDK runs (the server's check). The
|
|
25
|
-
* error names the file.
|
|
26
|
-
*/
|
|
27
|
-
export declare function loadManifest(root: string): LoadedManifest;
|
|
28
|
-
//# sourceMappingURL=prepare.d.ts.map
|