vintage-frames 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,28 +1,30 @@
1
+ import { VERSION as e } from "./version.js";
1
2
  //#region src/shell/app-file.ts
2
- var e = 1, t = 3, n = "vintage-frames.app", r = "vintage-frames.code", i = [
3
+ var t = 1, n = 2, r = 2, i = 3, a = "vintage-frames.app", o = "vintage-frames.code", s = [
3
4
  "id",
4
5
  "name",
5
6
  "version",
6
7
  "requires",
8
+ "api",
7
9
  "author",
8
10
  "description",
9
11
  "icon"
10
- ], a = Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10), o = Uint32Array.from({ length: 256 }, (e, t) => {
12
+ ], c = Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10), l = Uint32Array.from({ length: 256 }, (e, t) => {
11
13
  let n = t;
12
14
  for (let e = 0; e < 8; e++) n = n & 1 ? 3988292384 ^ n >>> 1 : n >>> 1;
13
15
  return n >>> 0;
14
16
  });
15
- function s(e) {
17
+ function u(e) {
16
18
  let t = 4294967295;
17
- for (let n of e) t = o[(t ^ n) & 255] ^ t >>> 8;
19
+ for (let n of e) t = l[(t ^ n) & 255] ^ t >>> 8;
18
20
  return (t ^ 4294967295) >>> 0;
19
21
  }
20
- function c(e) {
21
- if (e.length < 8 || a.some((t, n) => e[n] !== t)) return null;
22
+ function d(e) {
23
+ if (e.length < 8 || c.some((t, n) => e[n] !== t)) return null;
22
24
  let t = new DataView(e.buffer, e.byteOffset, e.byteLength), n = [], r = 8;
23
25
  for (; r + 12 <= e.length;) {
24
26
  let i = r + 12 + t.getUint32(r);
25
- if (i > e.length || s(e.subarray(r + 4, i - 4)) !== t.getUint32(i - 4)) return null;
27
+ if (i > e.length || u(e.subarray(r + 4, i - 4)) !== t.getUint32(i - 4)) return null;
26
28
  let a = String.fromCharCode(...e.subarray(r + 4, r + 8));
27
29
  if (n.push({
28
30
  type: a,
@@ -34,85 +36,91 @@ function c(e) {
34
36
  }
35
37
  return null;
36
38
  }
37
- function l(e) {
39
+ function f(e) {
38
40
  let t = e.indexOf(0);
39
41
  return t > 0 ? String.fromCharCode(...e.subarray(0, t)) : "";
40
42
  }
41
- var u = new TextDecoder("utf-8", { fatal: !0 });
42
- async function d(e) {
43
+ var p = new TextDecoder("utf-8", { fatal: !0 });
44
+ async function m(e) {
43
45
  let t = e.indexOf(0), n = e[t + 1], r = e[t + 2], i = e.indexOf(0, t + 3), a = i < 0 ? -1 : e.indexOf(0, i + 1);
44
46
  if (t < 1 || a < 0 || n > 1 || r !== 0) throw Error("a broken iTXt chunk");
45
47
  let o = e.subarray(a + 1);
46
- return u.decode(n ? await f(o) : o);
48
+ return p.decode(n ? await h(o) : o);
47
49
  }
48
- async function f(e) {
50
+ async function h(e) {
49
51
  let t = new Blob([e.slice()]).stream().pipeThrough(new DecompressionStream("deflate"));
50
52
  return new Uint8Array(await new Response(t).arrayBuffer());
51
53
  }
52
- async function p(e) {
54
+ async function g(e) {
53
55
  let t = new Blob([e.slice()]).stream().pipeThrough(new CompressionStream("deflate"));
54
56
  return new Uint8Array(await new Response(t).arrayBuffer());
55
57
  }
56
- function m(e) {
58
+ function _(e) {
57
59
  if (!e || typeof e != "object") return "its manifest is not an object";
58
60
  let t = e;
59
61
  if (t.format !== 1) return typeof t.format == "number" ? `it is format ${t.format}, and this kit reads format 1` : "its manifest has no format";
60
62
  let n = { format: 1 };
61
- for (let e of i) {
63
+ for (let e of s) {
62
64
  let r = t[e];
65
+ if (e === "api") {
66
+ if (r === void 0) continue;
67
+ if (!Number.isInteger(r) || r < 1) return `its api, ${JSON.stringify(r)}, is not a level`;
68
+ n.api = r;
69
+ continue;
70
+ }
63
71
  if (e === "description") {
64
72
  if (r !== void 0 && typeof r != "string") return "its description is not text";
65
73
  typeof r == "string" && r.trim() && (n.description = r);
66
74
  continue;
67
75
  }
68
76
  if (typeof r != "string" || !r) return `its manifest has no ${e}`;
69
- if (e === "version" && !y(r)) return `its version, ${r}, is not a version`;
70
- if (e === "requires" && !b(r)) return `its requires, ${r}, is not a range`;
77
+ if (e === "version" && !S(r)) return `its version, ${r}, is not a version`;
78
+ if (e === "requires" && !C(r)) return `its requires, ${r}, is not a range`;
71
79
  n[e] = r;
72
80
  }
73
81
  return n;
74
82
  }
75
- async function h(e) {
76
- let t = c(e);
83
+ async function v(e) {
84
+ let t = d(e);
77
85
  if (!t) return "it is not a whole PNG";
78
- let i = /* @__PURE__ */ new Map();
79
- for (let { type: e, data: n } of t) {
86
+ let n = /* @__PURE__ */ new Map();
87
+ for (let { type: e, data: r } of t) {
80
88
  if (e !== "iTXt") continue;
81
- let t = l(n);
89
+ let t = f(r);
82
90
  if (t === "vintage-frames.app" || t === "vintage-frames.code") {
83
- if (i.has(t)) return `it has two ${t} chunks`;
84
- i.set(t, n);
91
+ if (n.has(t)) return `it has two ${t} chunks`;
92
+ n.set(t, r);
85
93
  }
86
94
  }
87
- let a = i.get(n), o = i.get(r);
88
- if (!a && !o) return "it carries no application";
89
- if (!a) return "its manifest is missing";
90
- if (!o) return "its code is missing";
95
+ let r = n.get(a), i = n.get(o);
96
+ if (!r && !i) return "it carries no application";
97
+ if (!r) return "its manifest is missing";
98
+ if (!i) return "its code is missing";
91
99
  let s;
92
100
  try {
93
- s = JSON.parse(await d(a));
101
+ s = JSON.parse(await m(r));
94
102
  } catch {
95
103
  return "its manifest does not read";
96
104
  }
97
- let u = m(s);
98
- if (typeof u == "string") return u;
105
+ let c = _(s);
106
+ if (typeof c == "string") return c;
99
107
  try {
100
108
  return {
101
- manifest: u,
102
- code: await d(o)
109
+ manifest: c,
110
+ code: await m(i)
103
111
  };
104
112
  } catch {
105
113
  return "its code does not inflate";
106
114
  }
107
115
  }
108
- async function g(e) {
109
- let t = await h(e);
116
+ async function y(e) {
117
+ let t = await v(e);
110
118
  return typeof t == "string" ? null : t;
111
119
  }
112
- var _ = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
113
- function v(e) {
120
+ var b = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
121
+ function x(e) {
114
122
  if (typeof e != "string") return null;
115
- let t = _.exec(e.trim().replace(/^v/, ""));
123
+ let t = b.exec(e.trim().replace(/^v/, ""));
116
124
  return t ? {
117
125
  core: [
118
126
  Number(t[1]),
@@ -122,18 +130,18 @@ function v(e) {
122
130
  pre: t[4] ? t[4].split(".") : []
123
131
  } : null;
124
132
  }
125
- function y(e) {
126
- return _.test(e);
133
+ function S(e) {
134
+ return b.test(e);
127
135
  }
128
- function b(e) {
129
- return y(e.startsWith("^") ? e.slice(1) : e);
136
+ function C(e) {
137
+ return S(e.startsWith("^") ? e.slice(1) : e);
130
138
  }
131
- function x(e) {
139
+ function w(e) {
132
140
  if (typeof e != "string") return null;
133
141
  let t = e.trim();
134
- return v(t.startsWith("^") ? t.slice(1) : t);
142
+ return x(t.startsWith("^") ? t.slice(1) : t);
135
143
  }
136
- function S(e, t) {
144
+ function T(e, t) {
137
145
  for (let n = 0; n < 3; n++) if (e.core[n] !== t.core[n]) return e.core[n] - t.core[n];
138
146
  if (!e.pre.length || !t.pre.length) return t.pre.length - e.pre.length;
139
147
  for (let n = 0; n < Math.max(e.pre.length, t.pre.length); n++) {
@@ -146,14 +154,14 @@ function S(e, t) {
146
154
  }
147
155
  return 0;
148
156
  }
149
- function C(e, t) {
150
- let n = v(e), r = v(t);
151
- return n && r ? S(n, r) : !!n - +!!r;
157
+ function E(e, t) {
158
+ let n = x(e), r = x(t);
159
+ return n && r ? T(n, r) : !!n - +!!r;
152
160
  }
153
- function w(e, t) {
154
- let n = v(e), r = x(t);
161
+ function D(e, t) {
162
+ let n = x(e), r = w(t);
155
163
  if (!n || !r) return !1;
156
- if (!t.trim().startsWith("^")) return S(n, r) === 0;
164
+ if (!t.trim().startsWith("^")) return T(n, r) === 0;
157
165
  if (n.pre.length && !(r.pre.length && n.core.every((e, t) => e === r.core[t]))) return !1;
158
166
  let [i, a, o] = r.core, s = {
159
167
  core: i ? [
@@ -171,7 +179,11 @@ function w(e, t) {
171
179
  ],
172
180
  pre: []
173
181
  };
174
- return S(n, r) >= 0 && S(n, s) < 0;
182
+ return T(n, r) >= 0 && T(n, s) < 0;
183
+ }
184
+ function O(t) {
185
+ let { api: n } = t;
186
+ return n === void 0 ? D(e, t.requires) : Number.isInteger(n) && n >= 2 && n <= 2;
175
187
  }
176
188
  //#endregion
177
- export { e as APP_FILE_FORMAT, t as BOX_SCALE, r as CODE_KEYWORD, n as MANIFEST_KEYWORD, a as PNG_SIGNATURE, C as compareVersions, s as crc32, p as deflate, f as inflate, h as inspectAppFile, y as isVersion, l as itxtKeyword, m as manifestOf, c as pngChunks, g as readAppFile, w as satisfies };
189
+ export { n as APP_API, r as APP_API_OLDEST, t as APP_FILE_FORMAT, i as BOX_SCALE, o as CODE_KEYWORD, a as MANIFEST_KEYWORD, c as PNG_SIGNATURE, O as appRuns, E as compareVersions, u as crc32, g as deflate, h as inflate, v as inspectAppFile, S as isVersion, f as itxtKeyword, _ as manifestOf, d as pngChunks, y as readAppFile, D as satisfies };
@@ -13,6 +13,12 @@
13
13
  * never renamed, moved, copied or removed; nothing is made in the Trash.
14
14
  * Deleting is a move into the Trash, and only Empty Trash removes. A
15
15
  * volume's position is stored on a record of its own id.
16
+ * - The System Folder is kept the same way when the site names it: a folder
17
+ * on the startup disk (the desktop without one) holding Apple Menu Items
18
+ * and Startup Items, listed after the volumes. What they hold is anyone's,
19
+ * and the shell reads it: the Apple menu, and what opens at startup.
20
+ * - An alias stands for another item: its data names the original's id, and
21
+ * `resolve` finds the original wherever it moved, until it is removed.
16
22
  * - A folder never goes into itself or a folder inside it. A parent with no
17
23
  * record reads as the desktop.
18
24
  * - An item whose kind no application registers is left out of the listing
@@ -30,17 +36,25 @@ import type { Point } from './geometry.js';
30
36
  export declare const TRASH = "trash";
31
37
  /** The startup disk's id. */
32
38
  export declare const DISK = "disk";
39
+ /** The System Folder's id: kept on the startup disk when the site names it. */
40
+ export declare const SYSTEM_FOLDER = "system-folder";
41
+ /** Apple Menu Items' id, in the System Folder: what it holds is the Apple menu. */
42
+ export declare const APPLE_MENU_ITEMS = "apple-menu-items";
43
+ /** Startup Items' id, in the System Folder: what it holds opens at startup. */
44
+ export declare const STARTUP_ITEMS = "startup-items";
33
45
  /** A folder's kind. */
34
46
  export declare const FOLDER = "folder";
35
47
  /** An application's icon: the kind the shell registers, whose data names the application it opens. */
36
48
  export declare const APP_KIND = "app";
49
+ /** An alias: the kind the shell registers, whose data names the item it stands for. */
50
+ export declare const ALIAS_KIND = "alias";
37
51
  /** The name a new folder takes, counted up where it is taken. */
38
52
  export declare const UNTITLED_FOLDER = "untitled folder";
39
53
  /** One item of the catalog. */
40
54
  export interface Item {
41
55
  id: string;
42
56
  name: string;
43
- /** `folder`, a volume's (`trash`, `disk`), the shell's `app`, or a kind an application registers. */
57
+ /** `folder`, a volume's (`trash`, `disk`), the shell's `app` or `alias`, or a kind an application registers. */
44
58
  kind: string;
45
59
  /** A folder's id, a volume's, or null for the desktop. */
46
60
  parent: string | null;
@@ -78,9 +92,17 @@ export interface Volumes {
78
92
  trash?: string | false;
79
93
  disk?: string | false;
80
94
  }
95
+ /** The System Folder and its two folders, by name. A site that names them has them. */
96
+ export interface SystemFolders {
97
+ folder: string;
98
+ appleMenu: string;
99
+ startup: string;
100
+ }
81
101
  export interface CatalogOptions {
82
102
  storage: CatalogStorage | null;
83
103
  volumes?: Volumes;
104
+ /** The System Folder, on the startup disk. Unset, none. */
105
+ system?: SystemFolders;
84
106
  /** Whether an application registers `kind`. Folders are always listed. Default: every kind. */
85
107
  listed?(kind: string): boolean;
86
108
  /** A kind's payload hooks. */
@@ -109,10 +131,22 @@ export interface CatalogArchive {
109
131
  export declare const isContainerKind: (kind: string) => boolean;
110
132
  /** Whether `id` names a volume. */
111
133
  export declare const isVolume: (id: string | null | undefined) => boolean;
134
+ /**
135
+ * Whether `id` names a container the catalog keeps, never renamed, moved,
136
+ * copied or removed: a volume, the System Folder or a folder in it.
137
+ */
138
+ export declare const isKept: (id: string | null | undefined) => boolean;
112
139
  /** The application an `app` item stands for: its `data.app`, or null. */
113
140
  export declare function appIdOf(item: Item): string | null;
141
+ /** The id of the item an alias stands for: its `data.original`, or null for anything but an alias. */
142
+ export declare function originalOf(item: Item): string | null;
114
143
  /** The item with `id`, or null. */
115
144
  export declare function itemOf(state: CatalogState, id: string | null | undefined): Item | null;
145
+ /**
146
+ * The item `id` names, or the original an alias stands for, through an alias
147
+ * of an alias too. Null once the original is gone, and for a chain that loops.
148
+ */
149
+ export declare function resolve(state: CatalogState, id: string | null | undefined): Item | null;
116
150
  /** The container `parent` resolves to: that container while it is listed, else the desktop (null). */
117
151
  export declare function containerOf(state: CatalogState, parent: string | null | undefined): string | null;
118
152
  /** The items directly in a container (null: the desktop), in listing order. */
@@ -142,6 +176,12 @@ export declare function nextFolderName(state: CatalogState, parent: string | nul
142
176
  * then " copy 2", " copy 3", …
143
177
  */
144
178
  export declare function copyName(state: CatalogState, parent: string | null, name: string, kind: string): string;
179
+ /** The name for an alias of `name` in a container: "name alias", then "name alias 2", … while an alias there has it. */
180
+ export declare function aliasName(state: CatalogState, parent: string | null, name: string): string;
181
+ /** What Apple Menu Items holds, by name: the Apple menu's entries. None without the System Folder. */
182
+ export declare const appleMenuItemsOf: (state: CatalogState) => Item[];
183
+ /** What Startup Items holds, by name: what opens at startup. None without the System Folder. */
184
+ export declare const startupItemsOf: (state: CatalogState) => Item[];
145
185
  /** The catalog's operations, over its listing. */
146
186
  export interface Catalog {
147
187
  get(): CatalogState;