@inkandswitch/patchwork-pkg-base 0.0.81 → 0.0.83

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.
Files changed (51) hide show
  1. package/module-settings-url +1 -1
  2. package/package.json +1 -1
  3. package/packages/packages/dist/assets/mount-CgQfKq8z.js +1753 -0
  4. package/packages/packages/dist/index.js +1 -1
  5. package/packages/sideboard/dist/chunk-E6Y5RRIY.js +15 -0
  6. package/packages/sideboard/dist/chunk-E6Y5RRIY.js.map +7 -0
  7. package/packages/sideboard/dist/{chunk-DS3QVJZT.js → chunk-IBAIF3GD.js} +2 -2
  8. package/packages/sideboard/dist/chunk-RZPTJTVZ.js +2 -0
  9. package/packages/sideboard/dist/chunk-RZPTJTVZ.js.map +7 -0
  10. package/packages/sideboard/dist/chunk-YZ573CYO.js +2 -0
  11. package/packages/sideboard/dist/chunk-YZ573CYO.js.map +7 -0
  12. package/packages/sideboard/dist/{create-new-menu-VA4ELRJ6.js → create-new-menu-WF2LPUEV.js} +2 -2
  13. package/packages/sideboard/dist/document-list-panel-VY4FDLFY.js +2 -0
  14. package/packages/sideboard/dist/index.css +1 -1
  15. package/packages/sideboard/dist/index.css.map +2 -2
  16. package/packages/sideboard/dist/index.js +1 -1
  17. package/packages/sideboard/dist/item-menu-7ZNKM77G.js +2 -0
  18. package/packages/sideboard/dist/{item-menu-KCPJAERD.js.map → item-menu-7ZNKM77G.js.map} +1 -1
  19. package/packages/sideboard/dist/sideboard/sideboard.js +1 -1
  20. package/packages/threepane/dist/IsolatedDocumentArea-G3V7KYHJ.js +2 -0
  21. package/packages/threepane/dist/PatchworkFrame-R4CTQ6DV.js +2 -0
  22. package/packages/threepane/dist/PatchworkFrame-R4CTQ6DV.js.map +7 -0
  23. package/packages/threepane/dist/chunk-YC5AHP5G.js +841 -0
  24. package/packages/threepane/dist/chunk-YC5AHP5G.js.map +7 -0
  25. package/packages/threepane/dist/chunk-YERFWP5I.js +2 -0
  26. package/packages/threepane/dist/chunk-YERFWP5I.js.map +7 -0
  27. package/packages/threepane/dist/datatypes-YDAECNBI.js +2 -0
  28. package/packages/threepane/dist/index.js +1 -1
  29. package/plugin-registry-url +1 -1
  30. package/packages/packages/dist/assets/mount-Czkd2ZvO.js +0 -1660
  31. package/packages/sideboard/dist/chunk-4ROZGNSN.js +0 -15
  32. package/packages/sideboard/dist/chunk-4ROZGNSN.js.map +0 -7
  33. package/packages/sideboard/dist/chunk-OHHPMOAE.js +0 -2
  34. package/packages/sideboard/dist/chunk-OHHPMOAE.js.map +0 -7
  35. package/packages/sideboard/dist/chunk-ZQBDNEEV.js +0 -2
  36. package/packages/sideboard/dist/chunk-ZQBDNEEV.js.map +0 -7
  37. package/packages/sideboard/dist/document-list-panel-X3ZB5ZYJ.js +0 -2
  38. package/packages/sideboard/dist/item-menu-KCPJAERD.js +0 -2
  39. package/packages/threepane/dist/IsolatedDocumentArea-TH3ENI3M.js +0 -2
  40. package/packages/threepane/dist/PatchworkFrame-WMZ3SLEE.js +0 -2
  41. package/packages/threepane/dist/PatchworkFrame-WMZ3SLEE.js.map +0 -7
  42. package/packages/threepane/dist/chunk-ESMUVHPH.js +0 -2
  43. package/packages/threepane/dist/chunk-ESMUVHPH.js.map +0 -7
  44. package/packages/threepane/dist/chunk-FRVSEOM5.js +0 -969
  45. package/packages/threepane/dist/chunk-FRVSEOM5.js.map +0 -7
  46. package/packages/threepane/dist/datatypes-5DFL6VIN.js +0 -2
  47. /package/packages/sideboard/dist/{chunk-DS3QVJZT.js.map → chunk-IBAIF3GD.js.map} +0 -0
  48. /package/packages/sideboard/dist/{create-new-menu-VA4ELRJ6.js.map → create-new-menu-WF2LPUEV.js.map} +0 -0
  49. /package/packages/sideboard/dist/{document-list-panel-X3ZB5ZYJ.js.map → document-list-panel-VY4FDLFY.js.map} +0 -0
  50. /package/packages/threepane/dist/{IsolatedDocumentArea-TH3ENI3M.js.map → IsolatedDocumentArea-G3V7KYHJ.js.map} +0 -0
  51. /package/packages/threepane/dist/{datatypes-5DFL6VIN.js.map → datatypes-YDAECNBI.js.map} +0 -0
@@ -0,0 +1,1753 @@
1
+ import { insert, memo, effect, className, setAttribute, template, createComponent, delegateEvents, addEventListener, use, render } from "solid-js/web";
2
+ import { createSignal, onCleanup, createMemo, createEffect, createContext, useContext, Show, For } from "solid-js";
3
+ import { getAllRegistries } from "@inkandswitch/patchwork-plugins";
4
+ import * as filesystem from "@inkandswitch/patchwork-filesystem";
5
+ import { getImportableUrlFromAutomergeUrl } from "@inkandswitch/patchwork-filesystem";
6
+ function isAutomergeUrl(url) {
7
+ return typeof url === "string" && url.startsWith("automerge:");
8
+ }
9
+ function isHttpUrl(url) {
10
+ return typeof url === "string" && /^https?:/i.test(url);
11
+ }
12
+ function isInstallableUrl(url) {
13
+ if (isAutomergeUrl(url)) {
14
+ const id = documentIdOf(url);
15
+ return !!id && id.length >= 16;
16
+ }
17
+ if (isHttpUrl(url)) {
18
+ try {
19
+ new URL(url);
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+ return false;
26
+ }
27
+ function documentIdOf(url) {
28
+ if (!isAutomergeUrl(url)) return void 0;
29
+ const rest = url.slice("automerge:".length);
30
+ const match = rest.match(/^[^@?#/]+/);
31
+ return match ? match[0] : void 0;
32
+ }
33
+ function moduleKey(url) {
34
+ if (!url) return void 0;
35
+ return documentIdOf(url) ?? url;
36
+ }
37
+ function bareModuleUrl(url) {
38
+ if (!isAutomergeUrl(url)) return url;
39
+ const id = documentIdOf(url);
40
+ return id ? `automerge:${id}` : url;
41
+ }
42
+ function headsOf(url) {
43
+ if (!isAutomergeUrl(url)) return [];
44
+ const hash = url.indexOf("#");
45
+ if (hash < 0) return [];
46
+ const section = url.slice(hash + 1).replace(/[?].*$/, "");
47
+ return section ? section.split("|") : [];
48
+ }
49
+ function pinnedModuleUrl(importUrl, heads) {
50
+ const id = documentIdOf(importUrl);
51
+ if (!id || heads.length === 0) return void 0;
52
+ return `automerge:${id}#${[...heads].sort().join("|")}`;
53
+ }
54
+ function moduleKeySet(modules) {
55
+ const keys = /* @__PURE__ */ new Set();
56
+ for (const m of modules ?? []) {
57
+ const key = moduleKey(m);
58
+ if (key) keys.add(key);
59
+ }
60
+ return keys;
61
+ }
62
+ function classifyOrigin(importUrl, installedKeys, systemKeys) {
63
+ if (!importUrl) return "unknown";
64
+ const key = moduleKey(importUrl);
65
+ if (installedKeys.has(key)) return "installed";
66
+ if (systemKeys.has(key)) return "core";
67
+ if (!isAutomergeUrl(importUrl)) return "core";
68
+ return "ephemeral";
69
+ }
70
+ const ORIGIN_LABEL = {
71
+ installed: "my package list",
72
+ core: "system package list",
73
+ ephemeral: "ephemeral",
74
+ unknown: "unknown"
75
+ };
76
+ const ORIGIN_HINT = {
77
+ installed: "In the package list you're viewing.",
78
+ core: "From the site's default (system) package list.",
79
+ ephemeral: "Registered this session but not in any package list — install it to keep it after a reload.",
80
+ unknown: "No import URL, so its origin is unknown."
81
+ };
82
+ function originRank(origin) {
83
+ switch (origin) {
84
+ case "installed":
85
+ return 0;
86
+ case "ephemeral":
87
+ return 1;
88
+ case "core":
89
+ return 2;
90
+ default:
91
+ return 3;
92
+ }
93
+ }
94
+ function safeGetRegistries() {
95
+ try {
96
+ return getAllRegistries();
97
+ } catch {
98
+ return /* @__PURE__ */ new Map();
99
+ }
100
+ }
101
+ function readRegistrySnapshot() {
102
+ const out = [];
103
+ for (const [registry, reg] of safeGetRegistries()) {
104
+ let entries;
105
+ try {
106
+ entries = reg.all();
107
+ } catch {
108
+ continue;
109
+ }
110
+ for (const p of entries) {
111
+ if (!p || typeof p.id !== "string") continue;
112
+ out.push({
113
+ registry,
114
+ id: p.id,
115
+ type: typeof p.type === "string" ? p.type : registry,
116
+ name: typeof p.name === "string" ? p.name : p.id,
117
+ icon: p.icon,
118
+ importUrl: typeof p.importUrl === "string" ? p.importUrl : void 0,
119
+ supportedDatatypes: p.supportedDatatypes,
120
+ unlisted: p.unlisted === true ? true : void 0
121
+ });
122
+ }
123
+ }
124
+ return out;
125
+ }
126
+ function deactivateModule(importUrl) {
127
+ const key = moduleKey(importUrl);
128
+ if (!key) return;
129
+ for (const [, reg] of safeGetRegistries()) {
130
+ const registry = reg;
131
+ if (typeof registry.remove !== "function") continue;
132
+ let entries;
133
+ try {
134
+ entries = registry.all();
135
+ } catch {
136
+ continue;
137
+ }
138
+ for (const p of entries) {
139
+ if (!p || typeof p.id !== "string") continue;
140
+ if (moduleKey(p.importUrl) !== key) continue;
141
+ registry.remove(p.id);
142
+ }
143
+ }
144
+ }
145
+ function useLiveRegistries() {
146
+ const [tick, setTick] = createSignal(0);
147
+ const subs = /* @__PURE__ */ new Map();
148
+ const ensureSubscribed = () => {
149
+ for (const [, reg] of safeGetRegistries()) {
150
+ if (subs.has(reg)) continue;
151
+ try {
152
+ subs.set(reg, reg.on("changed", bump));
153
+ } catch {
154
+ }
155
+ }
156
+ };
157
+ function bump() {
158
+ ensureSubscribed();
159
+ setTick((t) => t + 1);
160
+ }
161
+ ensureSubscribed();
162
+ onCleanup(() => {
163
+ for (const off of subs.values()) {
164
+ try {
165
+ off();
166
+ } catch {
167
+ }
168
+ }
169
+ subs.clear();
170
+ });
171
+ const snapshot = createMemo(() => {
172
+ tick();
173
+ return readRegistrySnapshot();
174
+ });
175
+ return { snapshot };
176
+ }
177
+ function moduleWatcher() {
178
+ try {
179
+ return globalThis.window?.patchwork?.packages;
180
+ } catch {
181
+ return void 0;
182
+ }
183
+ }
184
+ function readSettingsSources() {
185
+ const mw = moduleWatcher();
186
+ if (!mw) return [];
187
+ const urls = mw.urls ?? {};
188
+ const out = [];
189
+ for (const name of Object.keys(urls)) {
190
+ const url = urls[name];
191
+ if (typeof url !== "string") continue;
192
+ let modules;
193
+ const handle = mw.handles?.[name];
194
+ if (handle?.doc) {
195
+ try {
196
+ modules = handle.doc()?.modules;
197
+ } catch {
198
+ }
199
+ }
200
+ if (!modules) modules = mw.staticManifests?.[name]?.modules;
201
+ out.push({
202
+ name,
203
+ url,
204
+ key: moduleKey(url) ?? url,
205
+ moduleKeys: moduleKeySet(modules)
206
+ });
207
+ }
208
+ return out;
209
+ }
210
+ function systemModuleKeys(sources, viewedKey) {
211
+ const keys = /* @__PURE__ */ new Set();
212
+ for (const source of sources) {
213
+ if (viewedKey && source.key === viewedKey) continue;
214
+ for (const key of source.moduleKeys) keys.add(key);
215
+ }
216
+ return keys;
217
+ }
218
+ function repo() {
219
+ try {
220
+ return globalThis.window?.repo;
221
+ } catch {
222
+ return void 0;
223
+ }
224
+ }
225
+ function useDocHeadsMap(urls) {
226
+ const [map, setMap] = createSignal({});
227
+ const subs = /* @__PURE__ */ new Map();
228
+ createEffect(() => {
229
+ const r = repo();
230
+ if (!r) return;
231
+ for (const url of urls()) {
232
+ if (!isAutomergeUrl(url)) continue;
233
+ const id = documentIdOf(url);
234
+ if (!id || subs.has(id)) continue;
235
+ subs.set(id, () => {
236
+ });
237
+ void r.find(bareModuleUrl(url)).then((handle) => {
238
+ const update = () => setMap((prev) => ({ ...prev, [id]: [...handle.heads()] }));
239
+ update();
240
+ handle.on("change", update);
241
+ subs.set(id, () => handle.off("change", update));
242
+ }).catch(() => {
243
+ subs.delete(id);
244
+ });
245
+ }
246
+ });
247
+ onCleanup(() => {
248
+ for (const off of subs.values()) {
249
+ try {
250
+ off();
251
+ } catch {
252
+ }
253
+ }
254
+ subs.clear();
255
+ });
256
+ return map;
257
+ }
258
+ async function fetchJson(url) {
259
+ try {
260
+ const res = await fetch(url);
261
+ if (!res.ok) return void 0;
262
+ return await res.json();
263
+ } catch {
264
+ return void 0;
265
+ }
266
+ }
267
+ function pickMeta(pkg) {
268
+ return {
269
+ name: typeof pkg?.name === "string" ? pkg.name : void 0,
270
+ title: typeof pkg?.title === "string" ? pkg.title : void 0,
271
+ version: typeof pkg?.version === "string" ? pkg.version : void 0
272
+ };
273
+ }
274
+ const BUILD_DIRS = /* @__PURE__ */ new Set([
275
+ "dist",
276
+ "build",
277
+ "lib",
278
+ "out",
279
+ "es",
280
+ "esm",
281
+ "cjs",
282
+ "umd",
283
+ "src",
284
+ "public",
285
+ "www"
286
+ ]);
287
+ function dirSegments(url) {
288
+ const parts = url.pathname.split("/").filter(Boolean);
289
+ const last = parts[parts.length - 1] ?? "";
290
+ if (/\.[a-z0-9]+$/i.test(last)) parts.pop();
291
+ return parts;
292
+ }
293
+ function endsInBuildDir(parts) {
294
+ return parts.length > 0 && BUILD_DIRS.has(parts[parts.length - 1].toLowerCase());
295
+ }
296
+ function pickPlugins(pkg) {
297
+ const arr = pkg?.plugins;
298
+ if (!Array.isArray(arr)) return null;
299
+ return arr.filter((p) => p && typeof p === "object").map((p) => ({
300
+ id: typeof p.id === "string" ? p.id : void 0,
301
+ name: typeof p.name === "string" ? p.name : void 0,
302
+ type: typeof p.type === "string" ? p.type : void 0,
303
+ supportedDatatypes: p.supportedDatatypes,
304
+ unlisted: p.unlisted === true ? true : void 0
305
+ }));
306
+ }
307
+ async function resolvePackageJson(importUrl) {
308
+ if (isAutomergeUrl(importUrl)) {
309
+ const base = getImportableUrlFromAutomergeUrl(
310
+ importUrl
311
+ );
312
+ const pkgUrl = new URL("package.json", base).href;
313
+ return fetchJson(pkgUrl);
314
+ }
315
+ if (isHttpUrl(importUrl)) {
316
+ try {
317
+ const u = new URL(importUrl);
318
+ const dirs = dirSegments(u);
319
+ const candidates = [dirs.join("/")];
320
+ while (endsInBuildDir(dirs)) {
321
+ dirs.pop();
322
+ candidates.push(dirs.join("/"));
323
+ }
324
+ for (const dir of candidates) {
325
+ const base = `${u.origin}/${dir}${dir ? "/" : ""}`;
326
+ const pkg = await fetchJson(new URL("package.json", base).href);
327
+ if (pkg && (pkg.name || pkg.title || Array.isArray(pkg.plugins)))
328
+ return pkg;
329
+ }
330
+ } catch {
331
+ }
332
+ }
333
+ return void 0;
334
+ }
335
+ async function resolvePackageMeta(importUrl) {
336
+ return pickMeta(await resolvePackageJson(importUrl) ?? {});
337
+ }
338
+ async function resolvePackageInfo(importUrl) {
339
+ const pkg = await resolvePackageJson(importUrl);
340
+ return { meta: pickMeta(pkg ?? {}), plugins: pickPlugins(pkg) };
341
+ }
342
+ function shortenAutomerge(url) {
343
+ const id = url.slice("automerge:".length).replace(/[@?#].*$/, "");
344
+ return id.length > 10 ? `automerge:${id.slice(0, 8)}…` : url;
345
+ }
346
+ function packageDisplayName(importUrl, meta) {
347
+ if (meta?.title) return meta.title;
348
+ if (meta?.name) return meta.name;
349
+ if (!importUrl) return "(unknown source)";
350
+ if (isAutomergeUrl(importUrl)) return shortenAutomerge(importUrl);
351
+ if (isHttpUrl(importUrl)) {
352
+ try {
353
+ const u = new URL(importUrl);
354
+ const parts = dirSegments(u);
355
+ while (endsInBuildDir(parts)) parts.pop();
356
+ return parts[parts.length - 1] || u.hostname;
357
+ } catch {
358
+ return importUrl;
359
+ }
360
+ }
361
+ return importUrl;
362
+ }
363
+ function usePackageData(handle) {
364
+ const [doc, setDoc] = createSignal(handle.doc());
365
+ const onChange = () => setDoc(handle.doc());
366
+ handle.on("change", onChange);
367
+ onCleanup(() => handle.off("change", onChange));
368
+ const installedKeys = createMemo(() => moduleKeySet(doc()?.modules));
369
+ const { snapshot } = useLiveRegistries();
370
+ const viewedKey = moduleKey(handle.url);
371
+ const settingsSources = createMemo(() => {
372
+ snapshot();
373
+ return readSettingsSources();
374
+ });
375
+ const systemKeys = createMemo(
376
+ () => systemModuleKeys(settingsSources(), viewedKey)
377
+ );
378
+ const systemPackageListUrl = createMemo(
379
+ () => settingsSources().find((source) => source.name === "system")?.url
380
+ );
381
+ const isCustomSystemPackageList = createMemo(
382
+ () => systemPackageListUrl() !== void 0 && systemPackageListUrl() !== "/modules.json"
383
+ );
384
+ const isWatchedPackageList = createMemo(
385
+ () => !!viewedKey && settingsSources().some((source) => source.key === viewedKey)
386
+ );
387
+ const headsByDoc = useDocHeadsMap(() => snapshot().map((e) => e.importUrl));
388
+ const headsFor = (importUrl) => {
389
+ if (!importUrl) return [];
390
+ const embedded = headsOf(importUrl);
391
+ if (embedded.length) return embedded;
392
+ const id = documentIdOf(importUrl);
393
+ return id && headsByDoc()[id] || [];
394
+ };
395
+ const [pkgMetas, setPkgMetas] = createSignal({});
396
+ const requested = /* @__PURE__ */ new Set();
397
+ createEffect(() => {
398
+ for (const entry of snapshot()) {
399
+ const url = entry.importUrl;
400
+ if (!url || requested.has(url)) continue;
401
+ requested.add(url);
402
+ void resolvePackageMeta(url).then(
403
+ (meta) => setPkgMetas((prev) => ({ ...prev, [url]: meta }))
404
+ );
405
+ }
406
+ });
407
+ const enriched = createMemo(() => {
408
+ const installed = installedKeys();
409
+ const system = systemKeys();
410
+ const metas = pkgMetas();
411
+ return snapshot().map((entry) => {
412
+ const meta = entry.importUrl ? metas[entry.importUrl] : void 0;
413
+ return {
414
+ ...entry,
415
+ origin: classifyOrigin(entry.importUrl, installed, system),
416
+ pkgMeta: meta,
417
+ pkgName: packageDisplayName(entry.importUrl, meta)
418
+ };
419
+ });
420
+ });
421
+ return {
422
+ doc,
423
+ installedKeys,
424
+ snapshot,
425
+ enriched,
426
+ headsFor,
427
+ systemPackageListUrl,
428
+ isCustomSystemPackageList,
429
+ isWatchedPackageList
430
+ };
431
+ }
432
+ let worker;
433
+ let nextRequestId = 1;
434
+ const pending = /* @__PURE__ */ new Map();
435
+ function getWorker() {
436
+ if (worker) return worker;
437
+ const w = new Worker("/module-loader-worker.js", {
438
+ type: "module",
439
+ name: "packages-module-loader"
440
+ });
441
+ w.addEventListener("message", (event) => {
442
+ const data = event.data;
443
+ if (!data || data.type !== "descriptors" && data.type !== "error") return;
444
+ const entry = pending.get(data.id);
445
+ if (!entry) return;
446
+ pending.delete(data.id);
447
+ if (data.type === "descriptors") entry.resolve(data.descriptors);
448
+ else entry.reject(new Error(data.error));
449
+ });
450
+ w.addEventListener("error", (event) => {
451
+ const error = new Error(
452
+ `module-loader worker error: ${event.message ?? "unknown"}`
453
+ );
454
+ for (const [, entry] of pending) entry.reject(error);
455
+ pending.clear();
456
+ worker = void 0;
457
+ });
458
+ worker = w;
459
+ return w;
460
+ }
461
+ function hostImporter() {
462
+ try {
463
+ const watcher = globalThis.window?.patchwork?.packages;
464
+ const importer = watcher?.importAutomergePackage;
465
+ return typeof importer === "function" ? importer.bind(watcher) : void 0;
466
+ } catch {
467
+ return void 0;
468
+ }
469
+ }
470
+ function discoverViaWorker(folderUrl, timeoutMs) {
471
+ const id = nextRequestId++;
472
+ return new Promise((resolve, reject) => {
473
+ const timer = setTimeout(() => {
474
+ if (pending.delete(id)) reject(new Error("Timed out importing the package"));
475
+ }, timeoutMs);
476
+ pending.set(id, {
477
+ resolve: (d) => {
478
+ clearTimeout(timer);
479
+ resolve(d);
480
+ },
481
+ reject: (e) => {
482
+ clearTimeout(timer);
483
+ reject(e);
484
+ }
485
+ });
486
+ try {
487
+ getWorker().postMessage({ type: "discover", id, url: folderUrl });
488
+ } catch (e) {
489
+ clearTimeout(timer);
490
+ pending.delete(id);
491
+ reject(e instanceof Error ? e : new Error(String(e)));
492
+ }
493
+ });
494
+ }
495
+ async function discoverPlugins(folderUrl, timeoutMs = 15e3) {
496
+ const importer = hostImporter();
497
+ if (!importer) return discoverViaWorker(folderUrl, timeoutMs);
498
+ const mod = await withTimeout(
499
+ importer(folderUrl),
500
+ timeoutMs,
501
+ "importing the package"
502
+ );
503
+ return descriptorsOf(mod);
504
+ }
505
+ function descriptorsOf(mod) {
506
+ const plugins = mod?.plugins;
507
+ return Array.isArray(plugins) ? plugins.map(toDescriptor) : [];
508
+ }
509
+ function toDescriptor(plugin) {
510
+ if (!plugin || typeof plugin !== "object") return {};
511
+ const { load, import: _import, module, ...description } = plugin;
512
+ return description;
513
+ }
514
+ function withTimeout(p, ms, what) {
515
+ return new Promise((resolve, reject) => {
516
+ const timer = setTimeout(
517
+ () => reject(new Error(`Timed out ${what}`)),
518
+ ms
519
+ );
520
+ p.then(
521
+ (v) => {
522
+ clearTimeout(timer);
523
+ resolve(v);
524
+ },
525
+ (e) => {
526
+ clearTimeout(timer);
527
+ reject(e);
528
+ }
529
+ );
530
+ });
531
+ }
532
+ async function discoverHttpPlugins(url, timeoutMs = 15e3) {
533
+ const mod = await withTimeout(
534
+ filesystem.importPackageFromHttpUrl(url),
535
+ timeoutMs,
536
+ "importing the package"
537
+ );
538
+ return descriptorsOf(mod);
539
+ }
540
+ function discoverPackagePlugins(url) {
541
+ return isAutomergeUrl(url) ? discoverPlugins(url) : discoverHttpPlugins(url);
542
+ }
543
+ function useBrokenModules(modules, snapshot) {
544
+ const pluginImportKeys = createMemo(() => {
545
+ const keys = /* @__PURE__ */ new Set();
546
+ for (const e of snapshot()) {
547
+ const k = moduleKey(e.importUrl);
548
+ if (k) keys.add(k);
549
+ }
550
+ return keys;
551
+ });
552
+ const orphanModules = createMemo(() => {
553
+ const registered = pluginImportKeys();
554
+ return (modules() ?? []).filter((m) => {
555
+ const k = moduleKey(m);
556
+ return !!k && !registered.has(k);
557
+ });
558
+ });
559
+ const [probes, setProbes] = createSignal({});
560
+ const probed = /* @__PURE__ */ new Set();
561
+ createEffect(() => {
562
+ for (const url of orphanModules()) {
563
+ const key = moduleKey(url);
564
+ if (!key || probed.has(key)) continue;
565
+ probed.add(key);
566
+ setProbes((p) => ({ ...p, [key]: { status: "loading" } }));
567
+ void discoverPackagePlugins(bareModuleUrl(url)).then(
568
+ () => setProbes((p) => ({ ...p, [key]: { status: "ok" } })),
569
+ (e) => setProbes((p) => ({
570
+ ...p,
571
+ // discoverPlugins rejects with the worker's stack as the message.
572
+ [key]: {
573
+ status: "error",
574
+ error: e instanceof Error ? e.message : String(e)
575
+ }
576
+ }))
577
+ );
578
+ }
579
+ });
580
+ const brokenModules = createMemo(
581
+ () => orphanModules().map((url) => ({ url, probe: probes()[moduleKey(url)] })).filter((b) => b.probe?.status === "error").map((b) => ({ url: b.url, error: b.probe.error ?? "Unknown error" }))
582
+ );
583
+ const [brokenInfo, setBrokenInfo] = createSignal({});
584
+ const brokenRequested = /* @__PURE__ */ new Set();
585
+ createEffect(() => {
586
+ for (const { url } of brokenModules()) {
587
+ const key = moduleKey(url);
588
+ if (!key || brokenRequested.has(key)) continue;
589
+ brokenRequested.add(key);
590
+ void resolvePackageInfo(bareModuleUrl(url)).then(
591
+ (info) => setBrokenInfo((prev) => ({ ...prev, [key]: info }))
592
+ );
593
+ }
594
+ });
595
+ const infoFor = (url) => brokenInfo()[moduleKey(url)];
596
+ return { brokenModules, infoFor };
597
+ }
598
+ const VIEW_LABEL = {
599
+ packages: "By package",
600
+ registries: "By type",
601
+ table: "Table"
602
+ };
603
+ function datatypesLabel(dt) {
604
+ if (dt === void 0) return null;
605
+ if (typeof dt === "string") return dt === "*" ? "any" : dt;
606
+ if (dt.includes("*")) return "any";
607
+ if (dt.length === 0) return "none";
608
+ return dt.join(", ");
609
+ }
610
+ function prettyType(type) {
611
+ const [ns, rest] = type.includes(":") ? type.split(/:(.*)/) : ["", type];
612
+ return ns === "patchwork" ? rest : type;
613
+ }
614
+ function filterEntries(entries, search, origin) {
615
+ const q = search.trim().toLowerCase();
616
+ return entries.filter((e) => {
617
+ if (origin !== "all" && e.origin !== origin) return false;
618
+ if (q) {
619
+ const hay = [
620
+ e.name,
621
+ e.id,
622
+ e.registry,
623
+ e.type,
624
+ e.importUrl,
625
+ e.pkgName,
626
+ datatypesLabel(e.supportedDatatypes),
627
+ e.unlisted ? "unlisted" : ""
628
+ ].filter(Boolean).join(" ").toLowerCase();
629
+ if (!hay.includes(q)) return false;
630
+ }
631
+ return true;
632
+ });
633
+ }
634
+ function countOrigins(entries) {
635
+ const counts = {
636
+ installed: 0,
637
+ ephemeral: 0,
638
+ core: 0,
639
+ unknown: 0
640
+ };
641
+ for (const e of entries) counts[e.origin]++;
642
+ return counts;
643
+ }
644
+ const byName = (a, b) => a.name.localeCompare(b.name);
645
+ function groupByPackage(entries) {
646
+ const groups = /* @__PURE__ */ new Map();
647
+ for (const e of entries) {
648
+ const key = e.importUrl ?? "∅";
649
+ let group = groups.get(key);
650
+ if (!group) {
651
+ group = {
652
+ importUrl: e.importUrl,
653
+ name: e.pkgName,
654
+ meta: e.pkgMeta,
655
+ origin: e.origin,
656
+ plugins: []
657
+ };
658
+ groups.set(key, group);
659
+ }
660
+ group.plugins.push(e);
661
+ }
662
+ const arr = [...groups.values()];
663
+ for (const g of arr) g.plugins.sort(byName);
664
+ arr.sort(
665
+ (a, b) => originRank(a.origin) - originRank(b.origin) || a.name.localeCompare(b.name)
666
+ );
667
+ return arr;
668
+ }
669
+ function groupByType(entries) {
670
+ const groups = /* @__PURE__ */ new Map();
671
+ for (const e of entries) {
672
+ const list = groups.get(e.registry);
673
+ if (list) list.push(e);
674
+ else groups.set(e.registry, [e]);
675
+ }
676
+ return [...groups.entries()].map(([registry, plugins]) => ({ registry, plugins: plugins.sort(byName) })).sort((a, b) => a.registry.localeCompare(b.registry));
677
+ }
678
+ function sortRows(entries, key, ascending) {
679
+ const dir = ascending ? 1 : -1;
680
+ const value = (e) => {
681
+ switch (key) {
682
+ case "registry":
683
+ return e.registry;
684
+ case "id":
685
+ return e.id;
686
+ case "package":
687
+ return e.pkgName;
688
+ case "origin":
689
+ return String(originRank(e.origin));
690
+ // Ascending groups the unlisted ones first — that's what you sort by
691
+ // this column to find.
692
+ case "unlisted":
693
+ return e.unlisted ? "0" : "1";
694
+ default:
695
+ return e.name;
696
+ }
697
+ };
698
+ return [...entries].sort(
699
+ (a, b) => value(a).localeCompare(value(b)) * dir || byName(a, b)
700
+ );
701
+ }
702
+ var _tmpl$$4 = /* @__PURE__ */ template(`<li class=pw-more><button class=pw-more__btn>`), _tmpl$2$4 = /* @__PURE__ */ template(`<span class=pw-packages__origin>`), _tmpl$3$4 = /* @__PURE__ */ template(`<span class=pw-packages__unlisted title="Hidden from new-document menus and pickers">unlisted`), _tmpl$4$4 = /* @__PURE__ */ template(`<code>`), _tmpl$5$4 = /* @__PURE__ */ template(`<span class=pw-plugin__supports><span class=pw-plugin__supports-label>supports</span> `), _tmpl$6$3 = /* @__PURE__ */ template(`<li class=pw-plugin><span class=pw-plugin__dot></span><span class=pw-plugin__name></span><span class=pw-plugin__type>`), _tmpl$7$3 = /* @__PURE__ */ template(`<span class=pw-plugin__type>`), _tmpl$8$3 = /* @__PURE__ */ template(`<span class=pw-install__plugin-supports>supports `), _tmpl$9$3 = /* @__PURE__ */ template(`<li class=pw-install__plugin><span class=pw-install__plugin-name>`), _tmpl$0$1 = /* @__PURE__ */ template(`<div class=pw-source__lines>`), _tmpl$1$1 = /* @__PURE__ */ template(`<span class=pw-source__none>no import url`), _tmpl$10$1 = /* @__PURE__ */ template(`<button class=pw-actions__btn>open`), _tmpl$11$1 = /* @__PURE__ */ template(`<button class="pw-actions__btn pw-actions__btn--danger"title="Remove this module from the settings doc you're viewing">delete`), _tmpl$12$1 = /* @__PURE__ */ template(`<div class=pw-actions>`);
703
+ const PackagesContext = createContext();
704
+ const PackagesProvider = PackagesContext.Provider;
705
+ function useActions() {
706
+ const actions = useContext(PackagesContext);
707
+ if (!actions) throw new Error("packages: bits used outside PackagesProvider");
708
+ return actions;
709
+ }
710
+ function Collapsible(props) {
711
+ const [expanded, setExpanded] = createSignal(false);
712
+ const limit = () => props.limit ?? 4;
713
+ const shown = createMemo(() => expanded() ? props.each : props.each.slice(0, limit()));
714
+ const hidden = () => Math.max(0, props.each.length - limit());
715
+ return [createComponent(For, {
716
+ get each() {
717
+ return shown();
718
+ },
719
+ children: (item) => props.render(item)
720
+ }), createComponent(Show, {
721
+ get when() {
722
+ return hidden() > 0;
723
+ },
724
+ get children() {
725
+ var _el$ = _tmpl$$4(), _el$2 = _el$.firstChild;
726
+ _el$2.$$click = () => setExpanded((v) => !v);
727
+ insert(_el$2, (() => {
728
+ var _c$ = memo(() => !!expanded());
729
+ return () => _c$() ? "show less" : `show ${hidden()} more`;
730
+ })());
731
+ return _el$;
732
+ }
733
+ })];
734
+ }
735
+ function OriginBadge(props) {
736
+ return (() => {
737
+ var _el$3 = _tmpl$2$4();
738
+ insert(_el$3, () => ORIGIN_LABEL[props.origin]);
739
+ effect((_p$) => {
740
+ var _v$ = props.origin, _v$2 = ORIGIN_HINT[props.origin];
741
+ _v$ !== _p$.e && setAttribute(_el$3, "data-origin", _p$.e = _v$);
742
+ _v$2 !== _p$.t && setAttribute(_el$3, "title", _p$.t = _v$2);
743
+ return _p$;
744
+ }, {
745
+ e: void 0,
746
+ t: void 0
747
+ });
748
+ return _el$3;
749
+ })();
750
+ }
751
+ function UnlistedBadge() {
752
+ return _tmpl$3$4();
753
+ }
754
+ function Copyable(props) {
755
+ const {
756
+ copied,
757
+ copy
758
+ } = useActions();
759
+ return (() => {
760
+ var _el$5 = _tmpl$4$4();
761
+ _el$5.$$click = () => copy(props.value);
762
+ insert(_el$5, (() => {
763
+ var _c$2 = memo(() => copied() === props.value);
764
+ return () => _c$2() ? "copied!" : props.label ?? props.value;
765
+ })());
766
+ effect((_p$) => {
767
+ var _v$3 = `pw-packages__copy ${props.class ?? ""}`, _v$4 = !!(copied() === props.value), _v$5 = props.title ?? "Click to copy";
768
+ _v$3 !== _p$.e && className(_el$5, _p$.e = _v$3);
769
+ _v$4 !== _p$.t && _el$5.classList.toggle("is-copied", _p$.t = _v$4);
770
+ _v$5 !== _p$.a && setAttribute(_el$5, "title", _p$.a = _v$5);
771
+ return _p$;
772
+ }, {
773
+ e: void 0,
774
+ t: void 0,
775
+ a: void 0
776
+ });
777
+ return _el$5;
778
+ })();
779
+ }
780
+ function PluginRow(props) {
781
+ const dts = () => datatypesLabel(props.plugin.supportedDatatypes);
782
+ return (() => {
783
+ var _el$6 = _tmpl$6$3(), _el$7 = _el$6.firstChild, _el$8 = _el$7.nextSibling, _el$9 = _el$8.nextSibling;
784
+ insert(_el$8, () => props.plugin.name);
785
+ insert(_el$9, () => prettyType(props.plugin.type));
786
+ insert(_el$6, createComponent(Show, {
787
+ get when() {
788
+ return props.plugin.unlisted;
789
+ },
790
+ get children() {
791
+ return createComponent(UnlistedBadge, {});
792
+ }
793
+ }), null);
794
+ insert(_el$6, createComponent(Copyable, {
795
+ get value() {
796
+ return props.plugin.id;
797
+ },
798
+ "class": "pw-plugin__id",
799
+ title: "Plugin id — click to copy"
800
+ }), null);
801
+ insert(_el$6, createComponent(Show, {
802
+ get when() {
803
+ return dts();
804
+ },
805
+ get children() {
806
+ var _el$0 = _tmpl$5$4(), _el$1 = _el$0.firstChild;
807
+ _el$1.nextSibling;
808
+ insert(_el$0, dts, null);
809
+ return _el$0;
810
+ }
811
+ }), null);
812
+ effect((_p$) => {
813
+ var _v$6 = props.plugin.origin, _v$7 = !!props.plugin.unlisted;
814
+ _v$6 !== _p$.e && setAttribute(_el$7, "data-origin", _p$.e = _v$6);
815
+ _v$7 !== _p$.t && _el$8.classList.toggle("is-unlisted", _p$.t = _v$7);
816
+ return _p$;
817
+ }, {
818
+ e: void 0,
819
+ t: void 0
820
+ });
821
+ return _el$6;
822
+ })();
823
+ }
824
+ function DeclaredPluginRow(props) {
825
+ const dts = () => datatypesLabel(props.plugin.supportedDatatypes);
826
+ return (() => {
827
+ var _el$11 = _tmpl$9$3(), _el$12 = _el$11.firstChild;
828
+ insert(_el$12, () => props.plugin.name || props.plugin.id);
829
+ insert(_el$11, createComponent(Show, {
830
+ get when() {
831
+ return props.plugin.type;
832
+ },
833
+ get children() {
834
+ var _el$13 = _tmpl$7$3();
835
+ insert(_el$13, () => prettyType(props.plugin.type));
836
+ return _el$13;
837
+ }
838
+ }), null);
839
+ insert(_el$11, createComponent(Show, {
840
+ get when() {
841
+ return props.plugin.unlisted;
842
+ },
843
+ get children() {
844
+ return createComponent(UnlistedBadge, {});
845
+ }
846
+ }), null);
847
+ insert(_el$11, createComponent(Show, {
848
+ get when() {
849
+ return dts();
850
+ },
851
+ get children() {
852
+ var _el$14 = _tmpl$8$3();
853
+ _el$14.firstChild;
854
+ insert(_el$14, dts, null);
855
+ return _el$14;
856
+ }
857
+ }), null);
858
+ effect(() => _el$12.classList.toggle("is-unlisted", !!props.plugin.unlisted));
859
+ return _el$11;
860
+ })();
861
+ }
862
+ function SourceLine(props) {
863
+ const {
864
+ headsFor
865
+ } = useActions();
866
+ const heads = () => headsFor(props.importUrl);
867
+ const pinned = () => pinnedModuleUrl(props.importUrl, heads());
868
+ return createComponent(Show, {
869
+ get when() {
870
+ return props.importUrl;
871
+ },
872
+ get fallback() {
873
+ return _tmpl$1$1();
874
+ },
875
+ get children() {
876
+ var _el$16 = _tmpl$0$1();
877
+ insert(_el$16, createComponent(Copyable, {
878
+ get value() {
879
+ return bareModuleUrl(props.importUrl);
880
+ },
881
+ "class": "pw-source__url",
882
+ title: "importUrl — click to copy"
883
+ }), null);
884
+ insert(_el$16, createComponent(Show, {
885
+ get when() {
886
+ return pinned();
887
+ },
888
+ get children() {
889
+ return createComponent(Copyable, {
890
+ get value() {
891
+ return pinned();
892
+ },
893
+ get label() {
894
+ return `heads ${heads().map((h) => h.slice(0, 7)).join(" ")}`;
895
+ },
896
+ "class": "pw-source__heads",
897
+ title: "Copy URL pinned to these heads"
898
+ });
899
+ }
900
+ }), null);
901
+ return _el$16;
902
+ }
903
+ });
904
+ }
905
+ const hasActions = (importUrl, origin) => isAutomergeUrl(importUrl) || origin === "installed";
906
+ function SourceActions(props) {
907
+ const {
908
+ openDoc,
909
+ uninstall
910
+ } = useActions();
911
+ return createComponent(Show, {
912
+ get when() {
913
+ return hasActions(props.importUrl, props.origin);
914
+ },
915
+ get children() {
916
+ var _el$18 = _tmpl$12$1();
917
+ insert(_el$18, createComponent(Show, {
918
+ get when() {
919
+ return isAutomergeUrl(props.importUrl);
920
+ },
921
+ get children() {
922
+ var _el$19 = _tmpl$10$1();
923
+ _el$19.$$click = () => openDoc(props.importUrl);
924
+ return _el$19;
925
+ }
926
+ }), null);
927
+ insert(_el$18, createComponent(Show, {
928
+ get when() {
929
+ return props.origin === "installed";
930
+ },
931
+ get children() {
932
+ var _el$20 = _tmpl$11$1();
933
+ _el$20.$$click = () => uninstall(props.importUrl);
934
+ return _el$20;
935
+ }
936
+ }), null);
937
+ return _el$18;
938
+ }
939
+ });
940
+ }
941
+ delegateEvents(["click"]);
942
+ var _tmpl$$3 = /* @__PURE__ */ template(`<ul class=pw-cards>`), _tmpl$2$3 = /* @__PURE__ */ template(`<span class=pw-card__version>v`), _tmpl$3$3 = /* @__PURE__ */ template(`<div class=pw-card__pkgname>`), _tmpl$4$3 = /* @__PURE__ */ template(`<footer class=pw-card__foot>`), _tmpl$5$3 = /* @__PURE__ */ template(`<li class=pw-card><header class=pw-card__head><h2 class=pw-card__name></h2><div class=pw-card__badges><span class=pw-card__count> plugin</span></div></header><div class=pw-card__source></div><ul class=pw-plugins>`), _tmpl$6$2 = /* @__PURE__ */ template(`<div class=pw-registries>`), _tmpl$7$2 = /* @__PURE__ */ template(`<section class=pw-registry><header class=pw-registry__head><h2 class=pw-registry__name></h2><span class=pw-registry__count></span></header><ul class=pw-reglist>`), _tmpl$8$2 = /* @__PURE__ */ template(`<span class=pw-regitem__supports>supports `), _tmpl$9$2 = /* @__PURE__ */ template(`<li class=pw-regitem><div class=pw-regitem__main><span class=pw-regitem__name></span></div><div class=pw-regitem__source><span class=pw-regitem__pkg>`), _tmpl$0 = /* @__PURE__ */ template(`<div class=pw-table-wrap><table class=pw-table><thead><tr><th class="pw-table__th pw-table__th--plain">importUrl</th></tr></thead><tbody>`), _tmpl$1 = /* @__PURE__ */ template(`<span class=pw-table__arrow>`), _tmpl$10 = /* @__PURE__ */ template(`<th class=pw-table__th>`), _tmpl$11 = /* @__PURE__ */ template(`<span class=pw-table__supports>`), _tmpl$12 = /* @__PURE__ */ template(`<span title="Hidden from new-document menus and pickers">✓`), _tmpl$13 = /* @__PURE__ */ template(`<tr class=pw-table__row><td class=pw-table__name></td><td class=pw-table__reg></td><td></td><td class=pw-table__pkg></td><td></td><td class=pw-table__flag></td><td class=pw-table__url><div class=pw-source>`);
943
+ function ByPackage(props) {
944
+ const groups = createMemo(() => groupByPackage(props.entries));
945
+ return (() => {
946
+ var _el$ = _tmpl$$3();
947
+ insert(_el$, createComponent(For, {
948
+ get each() {
949
+ return groups();
950
+ },
951
+ children: (group) => (() => {
952
+ var _el$2 = _tmpl$5$3(), _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$8 = _el$5.firstChild, _el$9 = _el$8.firstChild, _el$1 = _el$3.nextSibling, _el$10 = _el$1.nextSibling;
953
+ insert(_el$4, () => group.name);
954
+ insert(_el$5, createComponent(Show, {
955
+ get when() {
956
+ return group.meta?.version;
957
+ },
958
+ get children() {
959
+ var _el$6 = _tmpl$2$3();
960
+ _el$6.firstChild;
961
+ insert(_el$6, () => group.meta.version, null);
962
+ return _el$6;
963
+ }
964
+ }), _el$8);
965
+ insert(_el$5, createComponent(OriginBadge, {
966
+ get origin() {
967
+ return group.origin;
968
+ }
969
+ }), _el$8);
970
+ insert(_el$8, () => group.plugins.length, _el$9);
971
+ insert(_el$8, () => group.plugins.length === 1 ? "" : "s", null);
972
+ insert(_el$2, createComponent(Show, {
973
+ get when() {
974
+ return memo(() => !!group.meta?.name)() && group.meta?.name !== group.name;
975
+ },
976
+ get children() {
977
+ var _el$0 = _tmpl$3$3();
978
+ insert(_el$0, () => group.meta.name);
979
+ return _el$0;
980
+ }
981
+ }), _el$1);
982
+ insert(_el$1, createComponent(SourceLine, {
983
+ get importUrl() {
984
+ return group.importUrl;
985
+ }
986
+ }));
987
+ insert(_el$10, createComponent(Collapsible, {
988
+ get each() {
989
+ return group.plugins;
990
+ },
991
+ render: (plugin) => createComponent(PluginRow, {
992
+ plugin
993
+ })
994
+ }));
995
+ insert(_el$2, createComponent(Show, {
996
+ get when() {
997
+ return hasActions(group.importUrl, group.origin);
998
+ },
999
+ get children() {
1000
+ var _el$11 = _tmpl$4$3();
1001
+ insert(_el$11, createComponent(SourceActions, {
1002
+ get importUrl() {
1003
+ return group.importUrl;
1004
+ },
1005
+ get origin() {
1006
+ return group.origin;
1007
+ }
1008
+ }));
1009
+ return _el$11;
1010
+ }
1011
+ }), null);
1012
+ effect(() => setAttribute(_el$2, "data-origin", group.origin));
1013
+ return _el$2;
1014
+ })()
1015
+ }));
1016
+ return _el$;
1017
+ })();
1018
+ }
1019
+ function ByType(props) {
1020
+ const groups = createMemo(() => groupByType(props.entries));
1021
+ return (() => {
1022
+ var _el$12 = _tmpl$6$2();
1023
+ insert(_el$12, createComponent(For, {
1024
+ get each() {
1025
+ return groups();
1026
+ },
1027
+ children: (group) => (() => {
1028
+ var _el$13 = _tmpl$7$2(), _el$14 = _el$13.firstChild, _el$15 = _el$14.firstChild, _el$16 = _el$15.nextSibling, _el$17 = _el$14.nextSibling;
1029
+ insert(_el$15, () => group.registry);
1030
+ insert(_el$16, () => group.plugins.length);
1031
+ insert(_el$17, createComponent(Collapsible, {
1032
+ get each() {
1033
+ return group.plugins;
1034
+ },
1035
+ render: (plugin) => createComponent(TypeRow, {
1036
+ plugin
1037
+ })
1038
+ }));
1039
+ return _el$13;
1040
+ })()
1041
+ }));
1042
+ return _el$12;
1043
+ })();
1044
+ }
1045
+ function TypeRow(props) {
1046
+ const dts = () => datatypesLabel(props.plugin.supportedDatatypes);
1047
+ return (() => {
1048
+ var _el$18 = _tmpl$9$2(), _el$19 = _el$18.firstChild, _el$20 = _el$19.firstChild, _el$23 = _el$19.nextSibling, _el$24 = _el$23.firstChild;
1049
+ insert(_el$20, () => props.plugin.name);
1050
+ insert(_el$19, createComponent(Copyable, {
1051
+ get value() {
1052
+ return props.plugin.id;
1053
+ },
1054
+ "class": "pw-regitem__id",
1055
+ title: "Plugin id — click to copy"
1056
+ }), null);
1057
+ insert(_el$19, createComponent(OriginBadge, {
1058
+ get origin() {
1059
+ return props.plugin.origin;
1060
+ }
1061
+ }), null);
1062
+ insert(_el$19, createComponent(Show, {
1063
+ get when() {
1064
+ return props.plugin.unlisted;
1065
+ },
1066
+ get children() {
1067
+ return createComponent(UnlistedBadge, {});
1068
+ }
1069
+ }), null);
1070
+ insert(_el$19, createComponent(Show, {
1071
+ get when() {
1072
+ return dts();
1073
+ },
1074
+ get children() {
1075
+ var _el$21 = _tmpl$8$2();
1076
+ _el$21.firstChild;
1077
+ insert(_el$21, dts, null);
1078
+ return _el$21;
1079
+ }
1080
+ }), null);
1081
+ insert(_el$24, () => props.plugin.pkgName);
1082
+ insert(_el$23, createComponent(SourceLine, {
1083
+ get importUrl() {
1084
+ return props.plugin.importUrl;
1085
+ }
1086
+ }), null);
1087
+ insert(_el$23, createComponent(SourceActions, {
1088
+ get importUrl() {
1089
+ return props.plugin.importUrl;
1090
+ },
1091
+ get origin() {
1092
+ return props.plugin.origin;
1093
+ }
1094
+ }), null);
1095
+ effect((_p$) => {
1096
+ var _v$ = props.plugin.origin, _v$2 = !!props.plugin.unlisted;
1097
+ _v$ !== _p$.e && setAttribute(_el$18, "data-origin", _p$.e = _v$);
1098
+ _v$2 !== _p$.t && _el$20.classList.toggle("is-unlisted", _p$.t = _v$2);
1099
+ return _p$;
1100
+ }, {
1101
+ e: void 0,
1102
+ t: void 0
1103
+ });
1104
+ return _el$18;
1105
+ })();
1106
+ }
1107
+ const COLUMNS = [["name", "Name"], ["registry", "Registry"], ["id", "Id"], ["package", "Package"], ["origin", "Origin"], ["unlisted", "Unlisted"]];
1108
+ function Table(props) {
1109
+ const rows = createMemo(() => sortRows(props.entries, props.sortKey, props.sortAsc));
1110
+ return (() => {
1111
+ var _el$25 = _tmpl$0(), _el$26 = _el$25.firstChild, _el$27 = _el$26.firstChild, _el$28 = _el$27.firstChild, _el$29 = _el$28.firstChild, _el$30 = _el$27.nextSibling;
1112
+ insert(_el$28, createComponent(For, {
1113
+ each: COLUMNS,
1114
+ children: ([key, label]) => (() => {
1115
+ var _el$31 = _tmpl$10();
1116
+ _el$31.$$click = () => props.onSort(key);
1117
+ insert(_el$31, label, null);
1118
+ insert(_el$31, createComponent(Show, {
1119
+ get when() {
1120
+ return props.sortKey === key;
1121
+ },
1122
+ get children() {
1123
+ var _el$32 = _tmpl$1();
1124
+ insert(_el$32, () => props.sortAsc ? "▲" : "▼");
1125
+ return _el$32;
1126
+ }
1127
+ }), null);
1128
+ effect(() => setAttribute(_el$31, "data-sorted", props.sortKey === key ? "" : void 0));
1129
+ return _el$31;
1130
+ })()
1131
+ }), _el$29);
1132
+ insert(_el$30, createComponent(For, {
1133
+ get each() {
1134
+ return rows();
1135
+ },
1136
+ children: (e) => (() => {
1137
+ var _el$33 = _tmpl$13(), _el$34 = _el$33.firstChild, _el$36 = _el$34.nextSibling, _el$37 = _el$36.nextSibling, _el$38 = _el$37.nextSibling, _el$39 = _el$38.nextSibling, _el$40 = _el$39.nextSibling, _el$42 = _el$40.nextSibling, _el$43 = _el$42.firstChild;
1138
+ insert(_el$34, () => e.name, null);
1139
+ insert(_el$34, createComponent(Show, {
1140
+ get when() {
1141
+ return datatypesLabel(e.supportedDatatypes);
1142
+ },
1143
+ get children() {
1144
+ var _el$35 = _tmpl$11();
1145
+ insert(_el$35, () => datatypesLabel(e.supportedDatatypes));
1146
+ return _el$35;
1147
+ }
1148
+ }), null);
1149
+ insert(_el$36, () => e.registry);
1150
+ insert(_el$37, createComponent(Copyable, {
1151
+ get value() {
1152
+ return e.id;
1153
+ },
1154
+ "class": "pw-table__id"
1155
+ }));
1156
+ insert(_el$38, () => e.pkgName);
1157
+ insert(_el$39, createComponent(OriginBadge, {
1158
+ get origin() {
1159
+ return e.origin;
1160
+ }
1161
+ }));
1162
+ insert(_el$40, createComponent(Show, {
1163
+ get when() {
1164
+ return e.unlisted;
1165
+ },
1166
+ get children() {
1167
+ return _tmpl$12();
1168
+ }
1169
+ }));
1170
+ insert(_el$43, createComponent(SourceLine, {
1171
+ get importUrl() {
1172
+ return e.importUrl;
1173
+ }
1174
+ }), null);
1175
+ insert(_el$43, createComponent(SourceActions, {
1176
+ get importUrl() {
1177
+ return e.importUrl;
1178
+ },
1179
+ get origin() {
1180
+ return e.origin;
1181
+ }
1182
+ }), null);
1183
+ effect((_p$) => {
1184
+ var _v$3 = e.origin, _v$4 = !!e.unlisted;
1185
+ _v$3 !== _p$.e && setAttribute(_el$33, "data-origin", _p$.e = _v$3);
1186
+ _v$4 !== _p$.t && _el$34.classList.toggle("is-unlisted", _p$.t = _v$4);
1187
+ return _p$;
1188
+ }, {
1189
+ e: void 0,
1190
+ t: void 0
1191
+ });
1192
+ return _el$33;
1193
+ })()
1194
+ }));
1195
+ return _el$25;
1196
+ })();
1197
+ }
1198
+ delegateEvents(["click"]);
1199
+ var _tmpl$$2 = /* @__PURE__ */ template(`<div class=pw-broken>`), _tmpl$2$2 = /* @__PURE__ */ template(`<span class=pw-broken__name>`), _tmpl$3$2 = /* @__PURE__ */ template(`<span class=pw-card__version>v`), _tmpl$4$2 = /* @__PURE__ */ template(`<ul class="pw-install__plugins pw-broken__plugins">`), _tmpl$5$2 = /* @__PURE__ */ template(`<div class=pw-broken__box role=alert><div class=pw-broken__head><span class=pw-broken__label>Failed to import</span></div><pre class=pw-broken__trace>`);
1200
+ function BrokenModules(props) {
1201
+ return (() => {
1202
+ var _el$ = _tmpl$$2();
1203
+ insert(_el$, createComponent(For, {
1204
+ get each() {
1205
+ return props.modules;
1206
+ },
1207
+ children: (b) => {
1208
+ const meta = () => props.infoFor(b.url)?.meta;
1209
+ const declared = () => props.infoFor(b.url)?.plugins;
1210
+ return (() => {
1211
+ var _el$2 = _tmpl$5$2(), _el$3 = _el$2.firstChild;
1212
+ _el$3.firstChild;
1213
+ var _el$9 = _el$3.nextSibling;
1214
+ insert(_el$3, createComponent(Show, {
1215
+ get when() {
1216
+ return meta()?.title || meta()?.name;
1217
+ },
1218
+ get children() {
1219
+ return [(() => {
1220
+ var _el$5 = _tmpl$2$2();
1221
+ insert(_el$5, () => meta().title || meta().name);
1222
+ return _el$5;
1223
+ })(), createComponent(Show, {
1224
+ get when() {
1225
+ return meta()?.version;
1226
+ },
1227
+ get children() {
1228
+ var _el$6 = _tmpl$3$2();
1229
+ _el$6.firstChild;
1230
+ insert(_el$6, () => meta().version, null);
1231
+ return _el$6;
1232
+ }
1233
+ })];
1234
+ }
1235
+ }), null);
1236
+ insert(_el$3, createComponent(Copyable, {
1237
+ get value() {
1238
+ return b.url;
1239
+ },
1240
+ "class": "pw-broken__url",
1241
+ title: "module URL — click to copy"
1242
+ }), null);
1243
+ insert(_el$3, createComponent(SourceActions, {
1244
+ get importUrl() {
1245
+ return b.url;
1246
+ },
1247
+ origin: "installed"
1248
+ }), null);
1249
+ insert(_el$2, createComponent(Show, {
1250
+ get when() {
1251
+ return memo(() => !!declared())() && declared().length > 0;
1252
+ },
1253
+ get children() {
1254
+ var _el$8 = _tmpl$4$2();
1255
+ insert(_el$8, createComponent(For, {
1256
+ get each() {
1257
+ return declared();
1258
+ },
1259
+ children: (p) => createComponent(DeclaredPluginRow, {
1260
+ plugin: p
1261
+ })
1262
+ }));
1263
+ return _el$8;
1264
+ }
1265
+ }), _el$9);
1266
+ insert(_el$9, () => b.error);
1267
+ return _el$2;
1268
+ })();
1269
+ }
1270
+ }));
1271
+ return _el$;
1272
+ })();
1273
+ }
1274
+ var _tmpl$$1 = /* @__PURE__ */ template(`<div class=pw-install__error>`), _tmpl$2$1 = /* @__PURE__ */ template(`<div class=pw-install__loading>Reading package…`), _tmpl$3$1 = /* @__PURE__ */ template(`<span class=pw-install__version>v`), _tmpl$4$1 = /* @__PURE__ */ template(`<ul class=pw-install__plugins>`), _tmpl$5$1 = /* @__PURE__ */ template(`<div class=pw-install__card><div class=pw-install__card-head><h3 class=pw-install__pkg>`), _tmpl$6$1 = /* @__PURE__ */ template(`<div class=pw-install__preview>`), _tmpl$7$1 = /* @__PURE__ */ template(`<span class=pw-install__already>Already in your package list`), _tmpl$8$1 = /* @__PURE__ */ template(`<div class=pw-modal role=dialog aria-modal=true><div class=pw-install><header class=pw-install__head><h2 class=pw-install__title>Install a package</h2><button class=pw-install__close title=Close>×</button></header><p class=pw-install__blurb>Paste an <code>automerge:</code> or <code>https://</code> URL to add it to your package list.</p><input class=pw-install__input type=text autocomplete=off placeholder="automerge:… or https://…"><footer class=pw-install__foot><button class=pw-install__cancel>Cancel</button><button class=pw-install__add>Add to my package list`), _tmpl$9$1 = /* @__PURE__ */ template(`<div class=pw-install__none>`);
1275
+ async function previewPackage(url) {
1276
+ if (isAutomergeUrl(url)) {
1277
+ const bare = bareModuleUrl(url);
1278
+ const [pluginsResult2, meta] = await Promise.all([discoverPlugins(bare).then((plugins) => ({
1279
+ plugins
1280
+ }), (e) => ({
1281
+ error: e instanceof Error ? e.message : "Couldn't read the package."
1282
+ })), resolvePackageMeta(bare).catch(() => ({}))]);
1283
+ return {
1284
+ meta,
1285
+ plugins: "plugins" in pluginsResult2 ? pluginsResult2.plugins : null,
1286
+ error: "error" in pluginsResult2 ? pluginsResult2.error : void 0
1287
+ };
1288
+ }
1289
+ const [pluginsResult, info] = await Promise.all([discoverHttpPlugins(url).then((plugins) => ({
1290
+ plugins
1291
+ }), (e) => ({
1292
+ error: e instanceof Error ? e.message : "Couldn't import the package."
1293
+ })), resolvePackageInfo(url).catch(() => ({
1294
+ meta: {},
1295
+ plugins: null
1296
+ }))]);
1297
+ const imported = "plugins" in pluginsResult ? pluginsResult.plugins : null;
1298
+ const declared = info.plugins;
1299
+ return {
1300
+ meta: info.meta,
1301
+ plugins: imported && imported.length ? imported : declared,
1302
+ // Only surface the import failure when there are no declared plugins to
1303
+ // show in its place.
1304
+ error: "error" in pluginsResult && !(declared && declared.length) ? pluginsResult.error : void 0
1305
+ };
1306
+ }
1307
+ function InstallModal(props) {
1308
+ const [url, setUrl] = createSignal(props.initialUrl);
1309
+ const [busy, setBusy] = createSignal(false);
1310
+ const [plugins, setPlugins] = createSignal(null);
1311
+ const [meta, setMeta] = createSignal(null);
1312
+ const [error, setError] = createSignal(null);
1313
+ const target = createMemo(() => url().trim());
1314
+ const valid = createMemo(() => isInstallableUrl(target()));
1315
+ const alreadyInstalled = createMemo(() => {
1316
+ const key = moduleKey(target());
1317
+ return !!key && props.installedKeys.has(key);
1318
+ });
1319
+ const resetPreview = () => {
1320
+ setBusy(false);
1321
+ setPlugins(null);
1322
+ setMeta(null);
1323
+ setError(null);
1324
+ };
1325
+ let previewToken = 0;
1326
+ onCleanup(() => previewToken++);
1327
+ createEffect(() => {
1328
+ const raw = target();
1329
+ resetPreview();
1330
+ if (!raw) return;
1331
+ if (!valid()) {
1332
+ setError("That doesn't look like an automerge: or https:// URL.");
1333
+ return;
1334
+ }
1335
+ const token = ++previewToken;
1336
+ setBusy(true);
1337
+ const timer = setTimeout(() => {
1338
+ void previewPackage(raw).then((res) => {
1339
+ if (token !== previewToken) return;
1340
+ setBusy(false);
1341
+ setMeta(res.meta);
1342
+ setPlugins(res.plugins);
1343
+ if (res.error) setError(res.error);
1344
+ });
1345
+ }, 350);
1346
+ onCleanup(() => clearTimeout(timer));
1347
+ });
1348
+ const add = () => {
1349
+ if (!valid()) return;
1350
+ if (!alreadyInstalled()) props.onAdd(target());
1351
+ props.onClose();
1352
+ };
1353
+ return (() => {
1354
+ var _el$ = _tmpl$8$1(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$3.nextSibling, _el$7 = _el$6.nextSibling, _el$15 = _el$7.nextSibling, _el$17 = _el$15.firstChild, _el$18 = _el$17.nextSibling;
1355
+ _el$.$$keydown = (e) => {
1356
+ if (e.key === "Escape") props.onClose();
1357
+ };
1358
+ _el$.$$click = (e) => {
1359
+ if (e.target === e.currentTarget) props.onClose();
1360
+ };
1361
+ addEventListener(_el$5, "click", props.onClose, true);
1362
+ _el$7.$$keydown = (e) => {
1363
+ if (e.key === "Enter" && valid() && !alreadyInstalled()) {
1364
+ e.preventDefault();
1365
+ add();
1366
+ }
1367
+ };
1368
+ _el$7.$$input = (e) => setUrl(e.currentTarget.value);
1369
+ use((el) => setTimeout(() => el.focus(), 0), _el$7);
1370
+ setAttribute(_el$7, "spellcheck", false);
1371
+ insert(_el$2, createComponent(Show, {
1372
+ get when() {
1373
+ return target();
1374
+ },
1375
+ get children() {
1376
+ var _el$8 = _tmpl$6$1();
1377
+ insert(_el$8, createComponent(Show, {
1378
+ get when() {
1379
+ return error();
1380
+ },
1381
+ get children() {
1382
+ var _el$9 = _tmpl$$1();
1383
+ insert(_el$9, error);
1384
+ return _el$9;
1385
+ }
1386
+ }), null);
1387
+ insert(_el$8, createComponent(Show, {
1388
+ get when() {
1389
+ return busy();
1390
+ },
1391
+ get children() {
1392
+ return _tmpl$2$1();
1393
+ }
1394
+ }), null);
1395
+ insert(_el$8, createComponent(Show, {
1396
+ get when() {
1397
+ return memo(() => !!valid())() && (meta() || plugins());
1398
+ },
1399
+ get children() {
1400
+ var _el$1 = _tmpl$5$1(), _el$10 = _el$1.firstChild, _el$11 = _el$10.firstChild;
1401
+ insert(_el$11, () => meta()?.title || meta()?.name || packageDisplayName(bareModuleUrl(target()), meta() ?? void 0));
1402
+ insert(_el$10, createComponent(Show, {
1403
+ get when() {
1404
+ return meta()?.version;
1405
+ },
1406
+ get children() {
1407
+ var _el$12 = _tmpl$3$1();
1408
+ _el$12.firstChild;
1409
+ insert(_el$12, () => meta().version, null);
1410
+ return _el$12;
1411
+ }
1412
+ }), null);
1413
+ insert(_el$1, createComponent(Show, {
1414
+ get when() {
1415
+ return memo(() => !!plugins())() && plugins().length > 0;
1416
+ },
1417
+ get fallback() {
1418
+ return createComponent(Show, {
1419
+ get when() {
1420
+ return memo(() => !!!busy())() && !error();
1421
+ },
1422
+ get children() {
1423
+ var _el$19 = _tmpl$9$1();
1424
+ insert(_el$19, () => plugins() ? "No plugins reported by this package." : "Couldn't read this package's plugin list — you can still install it.");
1425
+ return _el$19;
1426
+ }
1427
+ });
1428
+ },
1429
+ get children() {
1430
+ var _el$14 = _tmpl$4$1();
1431
+ insert(_el$14, createComponent(For, {
1432
+ get each() {
1433
+ return plugins();
1434
+ },
1435
+ children: (p) => createComponent(DeclaredPluginRow, {
1436
+ plugin: p
1437
+ })
1438
+ }));
1439
+ return _el$14;
1440
+ }
1441
+ }), null);
1442
+ return _el$1;
1443
+ }
1444
+ }), null);
1445
+ return _el$8;
1446
+ }
1447
+ }), _el$15);
1448
+ insert(_el$15, createComponent(Show, {
1449
+ get when() {
1450
+ return alreadyInstalled();
1451
+ },
1452
+ get children() {
1453
+ return _tmpl$7$1();
1454
+ }
1455
+ }), _el$17);
1456
+ addEventListener(_el$17, "click", props.onClose, true);
1457
+ _el$18.$$click = add;
1458
+ effect(() => _el$18.disabled = !valid() || alreadyInstalled());
1459
+ effect(() => _el$7.value = url());
1460
+ return _el$;
1461
+ })();
1462
+ }
1463
+ delegateEvents(["click", "keydown", "input"]);
1464
+ var _tmpl$ = /* @__PURE__ */ template(`<span class=pw-packages__stat-of> / `), _tmpl$2 = /* @__PURE__ */ template(`<div class=pw-package-notice role=status>Using a custom system package list.`), _tmpl$3 = /* @__PURE__ */ template(`<div class=pw-package-notice role=alert>This package list is not being watched by this window.`), _tmpl$4 = /* @__PURE__ */ template(`<div class=pw-package-notices>`), _tmpl$5 = /* @__PURE__ */ template(`<div class=pw-packages><header class=pw-packages__head><div class=pw-packages__toolbar><input class=pw-packages__search type=text placeholder="Filter… or paste a URL to install"><div class=pw-packages__stats><span><strong></strong> plugins</span><span><strong></strong> packages</span><span><strong></strong> types</span></div></div><div class=pw-packages__tabbar><div class=pw-packages__tabs role=tablist></div><div class=pw-packages__origins>`), _tmpl$6 = /* @__PURE__ */ template(`<button class=pw-packages__tab>`), _tmpl$7 = /* @__PURE__ */ template(`<span class=pw-packages__origin-count>`), _tmpl$8 = /* @__PURE__ */ template(`<button class=pw-packages__origin-chip>`), _tmpl$9 = /* @__PURE__ */ template(`<div class=pw-packages__empty>`);
1465
+ const ORIGIN_CHIPS = [["all", "all"], ["installed", ORIGIN_LABEL.installed], ["core", ORIGIN_LABEL.core], ["ephemeral", ORIGIN_LABEL.ephemeral]];
1466
+ function Packages(props) {
1467
+ const data = usePackageData(props.handle);
1468
+ const broken = useBrokenModules(() => data.doc()?.modules, data.snapshot);
1469
+ const [view, setView] = createSignal("packages");
1470
+ const [search, setSearch] = createSignal("");
1471
+ const [originFilter, setOriginFilter] = createSignal("all");
1472
+ const [sortKey, setSortKey] = createSignal("name");
1473
+ const [sortAsc, setSortAsc] = createSignal(true);
1474
+ const originCounts = createMemo(() => countOrigins(data.enriched()));
1475
+ const filtered = createMemo(() => filterEntries(data.enriched(), search(), originFilter()));
1476
+ const stats = createMemo(() => {
1477
+ const rows = filtered();
1478
+ const packages = /* @__PURE__ */ new Set();
1479
+ const registries = /* @__PURE__ */ new Set();
1480
+ for (const e of rows) {
1481
+ packages.add(e.importUrl ?? "∅");
1482
+ registries.add(e.registry);
1483
+ }
1484
+ return {
1485
+ plugins: rows.length,
1486
+ total: data.enriched().length,
1487
+ packages: packages.size,
1488
+ registries: registries.size
1489
+ };
1490
+ });
1491
+ const toggleSort = (key) => {
1492
+ if (sortKey() === key) setSortAsc((v) => !v);
1493
+ else {
1494
+ setSortKey(key);
1495
+ setSortAsc(true);
1496
+ }
1497
+ };
1498
+ const [copied, setCopied] = createSignal(null);
1499
+ let copyTimer;
1500
+ onCleanup(() => clearTimeout(copyTimer));
1501
+ const actions = {
1502
+ copied,
1503
+ copy(value) {
1504
+ try {
1505
+ void navigator.clipboard?.writeText(value);
1506
+ } catch {
1507
+ }
1508
+ setCopied(value);
1509
+ clearTimeout(copyTimer);
1510
+ copyTimer = setTimeout(() => setCopied(null), 1200);
1511
+ },
1512
+ headsFor: data.headsFor,
1513
+ openDoc(url) {
1514
+ props.element.dispatchEvent(new CustomEvent("patchwork:open-document", {
1515
+ detail: {
1516
+ url
1517
+ },
1518
+ bubbles: true,
1519
+ composed: true
1520
+ }));
1521
+ },
1522
+ // Remove a module from the settings doc you're viewing AND deactivate its
1523
+ // plugins from the live registries so it disappears now, not just on
1524
+ // reload. The doc stores bare module URLs while a plugin's importUrl is
1525
+ // heads-pinned, so both sides match by key.
1526
+ uninstall(importUrl) {
1527
+ const key = moduleKey(importUrl);
1528
+ if (!key) return;
1529
+ props.handle.change((d) => {
1530
+ if (!Array.isArray(d.modules)) return;
1531
+ const idx = d.modules.findIndex((m) => moduleKey(m) === key);
1532
+ if (idx >= 0) d.modules.splice(idx, 1);
1533
+ });
1534
+ deactivateModule(importUrl);
1535
+ }
1536
+ };
1537
+ const [installUrl, setInstallUrl] = createSignal(null);
1538
+ const install = (url) => {
1539
+ const key = moduleKey(url);
1540
+ if (!key) return;
1541
+ props.handle.change((d) => {
1542
+ if (!Array.isArray(d.modules)) d.modules = [];
1543
+ if (!d.modules.some((m) => moduleKey(m) === key)) d.modules.push(url);
1544
+ });
1545
+ };
1546
+ const onSearchPaste = (event) => {
1547
+ const pasted = event.clipboardData?.getData("text")?.trim() ?? "";
1548
+ if (!isInstallableUrl(pasted)) return;
1549
+ event.preventDefault();
1550
+ setInstallUrl(pasted);
1551
+ };
1552
+ return createComponent(PackagesProvider, {
1553
+ value: actions,
1554
+ get children() {
1555
+ var _el$ = _tmpl$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, _el$6 = _el$5.firstChild, _el$7 = _el$6.firstChild, _el$0 = _el$7.nextSibling, _el$1 = _el$6.nextSibling, _el$10 = _el$1.firstChild, _el$11 = _el$1.nextSibling, _el$12 = _el$11.firstChild, _el$13 = _el$3.nextSibling, _el$14 = _el$13.firstChild, _el$15 = _el$14.nextSibling;
1556
+ _el$4.addEventListener("paste", onSearchPaste);
1557
+ _el$4.$$input = (e) => setSearch(e.currentTarget.value);
1558
+ insert(_el$7, () => stats().plugins);
1559
+ insert(_el$6, createComponent(Show, {
1560
+ get when() {
1561
+ return stats().plugins !== stats().total;
1562
+ },
1563
+ get children() {
1564
+ var _el$8 = _tmpl$();
1565
+ _el$8.firstChild;
1566
+ insert(_el$8, () => stats().total, null);
1567
+ return _el$8;
1568
+ }
1569
+ }), _el$0);
1570
+ insert(_el$10, () => stats().packages);
1571
+ insert(_el$12, () => stats().registries);
1572
+ insert(_el$14, createComponent(For, {
1573
+ each: ["packages", "registries", "table"],
1574
+ children: (v) => (() => {
1575
+ var _el$20 = _tmpl$6();
1576
+ _el$20.$$click = () => setView(v);
1577
+ setAttribute(_el$20, "data-view", v);
1578
+ insert(_el$20, () => VIEW_LABEL[v]);
1579
+ effect(() => setAttribute(_el$20, "data-active", view() === v ? "" : void 0));
1580
+ return _el$20;
1581
+ })()
1582
+ }));
1583
+ insert(_el$15, createComponent(For, {
1584
+ each: ORIGIN_CHIPS,
1585
+ children: ([key, label]) => (() => {
1586
+ var _el$21 = _tmpl$8();
1587
+ _el$21.$$click = () => setOriginFilter(key);
1588
+ setAttribute(_el$21, "data-origin", key === "all" ? void 0 : key);
1589
+ insert(_el$21, label, null);
1590
+ insert(_el$21, createComponent(Show, {
1591
+ when: key !== "all",
1592
+ get children() {
1593
+ var _el$22 = _tmpl$7();
1594
+ insert(_el$22, () => originCounts()[key]);
1595
+ return _el$22;
1596
+ }
1597
+ }), null);
1598
+ effect((_p$) => {
1599
+ var _v$ = originFilter() === key ? "" : void 0, _v$2 = key === "all" ? void 0 : ORIGIN_HINT[key];
1600
+ _v$ !== _p$.e && setAttribute(_el$21, "data-active", _p$.e = _v$);
1601
+ _v$2 !== _p$.t && setAttribute(_el$21, "title", _p$.t = _v$2);
1602
+ return _p$;
1603
+ }, {
1604
+ e: void 0,
1605
+ t: void 0
1606
+ });
1607
+ return _el$21;
1608
+ })()
1609
+ }));
1610
+ insert(_el$, createComponent(Show, {
1611
+ get when() {
1612
+ return data.isCustomSystemPackageList() || !data.isWatchedPackageList();
1613
+ },
1614
+ get children() {
1615
+ var _el$16 = _tmpl$4();
1616
+ insert(_el$16, createComponent(Show, {
1617
+ get when() {
1618
+ return data.isCustomSystemPackageList();
1619
+ },
1620
+ get children() {
1621
+ var _el$17 = _tmpl$2();
1622
+ _el$17.firstChild;
1623
+ insert(_el$17, createComponent(Copyable, {
1624
+ get value() {
1625
+ return data.systemPackageListUrl();
1626
+ },
1627
+ "class": "pw-package-notice__url",
1628
+ title: "System package list URL — click to copy"
1629
+ }), null);
1630
+ return _el$17;
1631
+ }
1632
+ }), null);
1633
+ insert(_el$16, createComponent(Show, {
1634
+ get when() {
1635
+ return !data.isWatchedPackageList();
1636
+ },
1637
+ get children() {
1638
+ return _tmpl$3();
1639
+ }
1640
+ }), null);
1641
+ return _el$16;
1642
+ }
1643
+ }), null);
1644
+ insert(_el$, createComponent(Show, {
1645
+ get when() {
1646
+ return memo(() => view() === "packages")() && broken.brokenModules().length > 0;
1647
+ },
1648
+ get children() {
1649
+ return createComponent(BrokenModules, {
1650
+ get modules() {
1651
+ return broken.brokenModules();
1652
+ },
1653
+ get infoFor() {
1654
+ return broken.infoFor;
1655
+ }
1656
+ });
1657
+ }
1658
+ }), null);
1659
+ insert(_el$, createComponent(Show, {
1660
+ get when() {
1661
+ return filtered().length > 0;
1662
+ },
1663
+ get fallback() {
1664
+ return (() => {
1665
+ var _el$23 = _tmpl$9();
1666
+ insert(_el$23, createComponent(Show, {
1667
+ get when() {
1668
+ return data.enriched().length > 0;
1669
+ },
1670
+ get fallback() {
1671
+ return "No plugins are registered yet.";
1672
+ },
1673
+ children: "Nothing matches these filters."
1674
+ }));
1675
+ return _el$23;
1676
+ })();
1677
+ },
1678
+ get children() {
1679
+ return [createComponent(Show, {
1680
+ get when() {
1681
+ return view() === "packages";
1682
+ },
1683
+ get children() {
1684
+ return createComponent(ByPackage, {
1685
+ get entries() {
1686
+ return filtered();
1687
+ }
1688
+ });
1689
+ }
1690
+ }), createComponent(Show, {
1691
+ get when() {
1692
+ return view() === "registries";
1693
+ },
1694
+ get children() {
1695
+ return createComponent(ByType, {
1696
+ get entries() {
1697
+ return filtered();
1698
+ }
1699
+ });
1700
+ }
1701
+ }), createComponent(Show, {
1702
+ get when() {
1703
+ return view() === "table";
1704
+ },
1705
+ get children() {
1706
+ return createComponent(Table, {
1707
+ get entries() {
1708
+ return filtered();
1709
+ },
1710
+ get sortKey() {
1711
+ return sortKey();
1712
+ },
1713
+ get sortAsc() {
1714
+ return sortAsc();
1715
+ },
1716
+ onSort: toggleSort
1717
+ });
1718
+ }
1719
+ })];
1720
+ }
1721
+ }), null);
1722
+ insert(_el$, createComponent(Show, {
1723
+ get when() {
1724
+ return installUrl() !== null;
1725
+ },
1726
+ get children() {
1727
+ return createComponent(InstallModal, {
1728
+ get initialUrl() {
1729
+ return installUrl();
1730
+ },
1731
+ get installedKeys() {
1732
+ return data.installedKeys();
1733
+ },
1734
+ onAdd: install,
1735
+ onClose: () => setInstallUrl(null)
1736
+ });
1737
+ }
1738
+ }), null);
1739
+ effect(() => _el$4.value = search());
1740
+ return _el$;
1741
+ }
1742
+ });
1743
+ }
1744
+ delegateEvents(["input", "click"]);
1745
+ function mount(handle, element) {
1746
+ return render(() => createComponent(Packages, {
1747
+ handle,
1748
+ element
1749
+ }), element);
1750
+ }
1751
+ export {
1752
+ mount
1753
+ };