@ingcreators/annot-core 0.2.0 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,80 @@
1
1
  # @ingcreators/annot-core
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - f485646: **Expose `./xmp-bytes` subpath on the published tarball.**
8
+ The workspace `package.json#exports` declared
9
+ `"./xmp-bytes": "./src/xmp/xmp-bytes.ts"` from day one, but
10
+ `publishConfig.exports` only declared `.` + `./styles/*` —
11
+ so every workspace subpath (`./headless`, `./editor/*`,
12
+ `./xmp-bytes`, etc.) was stripped from the published
13
+ tarball.
14
+
15
+ This patch unblocks the `./xmp-bytes` subpath specifically.
16
+ `@ingcreators/annot-product-docs-astro@0.2.1`'s playwright
17
+ fixture imports `@ingcreators/annot-core/xmp-bytes` (via
18
+ the bundled `writePngWithTagsOnly` helper); without this
19
+ patch, any consumer doing
20
+ `import { test } from "@ingcreators/annot-product-docs-astro/playwright"`
21
+ hits `Package subpath './xmp-bytes' is not defined`.
22
+
23
+ ## Fix
24
+
25
+ `vite.config.ts` switches to multi-entry library mode:
26
+
27
+ ```ts
28
+ lib: {
29
+ entry: {
30
+ index: resolve(__dirname, "src/index.ts"),
31
+ "xmp-bytes": resolve(__dirname, "src/xmp/xmp-bytes.ts"),
32
+ },
33
+ formats: ["es"],
34
+ },
35
+ ```
36
+
37
+ `package.json#publishConfig.exports` gains the matching
38
+ `./xmp-bytes` entry:
39
+
40
+ ```json
41
+ "./xmp-bytes": {
42
+ "types": "./dist/xmp/xmp-bytes.d.ts",
43
+ "default": "./dist/xmp-bytes.js"
44
+ }
45
+ ```
46
+
47
+ Bundle landing in the tarball:
48
+
49
+ ```
50
+ dist/xmp-bytes.js 7.55 kB │ gzip: 2.67 kB
51
+ dist/xmp/xmp-bytes.d.ts declarations colocated by the dts plugin
52
+ ```
53
+
54
+ ## Other subpaths still missing
55
+
56
+ The workspace `exports` map declares 17+ subpaths (`./headless`,
57
+ `./editor`, `./editor/*`, `./icons`, `./xmp`, `./zip`,
58
+ `./utils`, `./desktop-bridge`, `./storage`, `./encode/*`,
59
+ `./auto-capture-options`, …). Most are Tier C (browser-only)
60
+ and shouldn't ship as standalone published bundles — Tier C
61
+ code lives in `@ingcreators/annot-editor` / `-render` for
62
+ npm consumers. The few Tier A subpaths that DO make sense
63
+ on npm (`./headless`, `./storage`, `./utils`, `./zip`,
64
+ `./zip-bytes`) can ship in a separate follow-up patch
65
+ when a concrete downstream consumer needs them.
66
+
67
+ ## After this PR republishes
68
+
69
+ `@ingcreators/annot-product-docs-astro` needs a `0.2.2`
70
+ republish that bumps its `@ingcreators/annot-core` dep
71
+ from `0.2.0` to `^0.2.1` so the playwright fixture can
72
+ finally resolve `./xmp-bytes` at consumer install time.
73
+ Once both land, the `examples/workflow-app/` tour can
74
+ migrate from the hybrid `captureScreen + page.screenshot`
75
+ pair to the unified `page.screenshot({ annot: { mdx } })`
76
+ single call.
77
+
3
78
  ## 0.2.0
4
79
 
5
80
  ### Minor Changes
@@ -0,0 +1,265 @@
1
+ //#region src/xmp/xmp-bytes.ts
2
+ var e = "annot", t = "https://ingcreators.com/annot/ns/1.0/", n = new TextEncoder().encode("http://ns.adobe.com/xap/1.0/\0"), r = new TextEncoder().encode("annot:OriginalImage\0"), i = new TextEncoder().encode("XML:com.adobe.xmp");
3
+ function a(n, r, i, a) {
4
+ let o = a && Object.keys(a).length > 0 ? JSON.stringify(a) : "";
5
+ return `<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
6
+ <x:xmpmeta xmlns:x="adobe:ns:meta/">
7
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
8
+ <rdf:Description rdf:about=""
9
+ xmlns:${e}="${t}">
10
+ <${e}:annotations><![CDATA[${n}]]></${e}:annotations>
11
+ <${e}:width>${r}</${e}:width>
12
+ <${e}:height>${i}</${e}:height>
13
+ <${e}:version>1.0</${e}:version>${o ? `\n <${e}:tags>${o}</${e}:tags>` : ""}
14
+ </rdf:Description>
15
+ </rdf:RDF>
16
+ </x:xmpmeta>
17
+ <?xpacket end="w"?>`;
18
+ }
19
+ function o(e) {
20
+ return new Uint8Array([e >> 8 & 255, e & 255]);
21
+ }
22
+ function s(e) {
23
+ return new Uint8Array([
24
+ e >> 24 & 255,
25
+ e >> 16 & 255,
26
+ e >> 8 & 255,
27
+ e & 255
28
+ ]);
29
+ }
30
+ function c(e, t) {
31
+ return e[t] << 8 | e[t + 1];
32
+ }
33
+ function l(e, t) {
34
+ return (e[t] << 24 | e[t + 1] << 16 | e[t + 2] << 8 | e[t + 3]) >>> 0;
35
+ }
36
+ function u(...e) {
37
+ let t = 0;
38
+ for (let n of e) t += n.length;
39
+ let n = new Uint8Array(t), r = 0;
40
+ for (let t of e) n.set(t, r), r += t.length;
41
+ return n;
42
+ }
43
+ function d(e, t, n) {
44
+ if (t + n.length > e.length) return !1;
45
+ for (let r = 0; r < n.length; r++) if (e[t + r] !== n[r]) return !1;
46
+ return !0;
47
+ }
48
+ function f(e) {
49
+ let t = e.split(",")[1] || "", n = atob(t), r = new Uint8Array(n.length);
50
+ for (let e = 0; e < n.length; e++) r[e] = n.charCodeAt(e);
51
+ return r;
52
+ }
53
+ function p(e, t) {
54
+ let n = t.length + 2;
55
+ return u(new Uint8Array([255, e]), o(n), t);
56
+ }
57
+ function m(e) {
58
+ let t = 65533 - r.length - 4, n = Math.ceil(e.length / t), i = [];
59
+ for (let a = 0; a < n; a++) {
60
+ let s = a * t, c = Math.min(s + t, e.length), l = e.slice(s, c), d = u(r, o(a), o(n), l);
61
+ i.push(p(226, d));
62
+ }
63
+ return u(...i);
64
+ }
65
+ function h(e) {
66
+ let t = [e.slice(0, 2)], i = 2;
67
+ for (; i + 4 <= e.length && e[i] === 255;) {
68
+ let a = e[i + 1];
69
+ if (a === 217 || a === 218) return t.push(e.slice(i)), u(...t);
70
+ let o = c(e, i + 2), s = i + 2 + o;
71
+ if (s > e.length) break;
72
+ let l = a === 225 && d(e, i + 4, n), f = a === 226 && d(e, i + 4, r);
73
+ !l && !f && t.push(e.slice(i, s)), i = s;
74
+ }
75
+ return i < e.length && t.push(e.slice(i)), u(...t);
76
+ }
77
+ function g(e, t, r) {
78
+ let i = p(225, u(n, t)), a = m(r), o = h(e);
79
+ return u(o.slice(0, 2), i, a, o.slice(2));
80
+ }
81
+ var _ = (() => {
82
+ let e = new Uint32Array(256);
83
+ for (let t = 0; t < 256; t++) {
84
+ let n = t;
85
+ for (let e = 0; e < 8; e++) n & 1 ? n = 3988292384 ^ n >>> 1 : n >>>= 1;
86
+ e[t] = n;
87
+ }
88
+ return e;
89
+ })();
90
+ function v(e) {
91
+ let t = 4294967295;
92
+ for (let n = 0; n < e.length; n++) t = _[(t ^ e[n]) & 255] ^ t >>> 8;
93
+ return (t ^ 4294967295) >>> 0;
94
+ }
95
+ function y(e, t) {
96
+ let n = u(e, t), r = v(n);
97
+ return u(s(t.length), n, s(r));
98
+ }
99
+ function b(e) {
100
+ let t = u(i, new Uint8Array([
101
+ 0,
102
+ 0,
103
+ 0,
104
+ 0,
105
+ 0
106
+ ]), e);
107
+ return y(new TextEncoder().encode("iTXt"), t);
108
+ }
109
+ function x(e) {
110
+ let t = [e.slice(0, 8)], n = 8;
111
+ for (; n + 12 <= e.length;) {
112
+ let r = l(e, n), a = e.slice(n + 4, n + 8), o = n + 8, s = o + r + 4;
113
+ if (s > e.length) break;
114
+ let c = String.fromCharCode(...a);
115
+ !(c === "iTXt" && d(e, o, i)) && c !== "svGo" && t.push(e.slice(n, s)), n = s;
116
+ }
117
+ return u(...t);
118
+ }
119
+ function S(e, t, n) {
120
+ let r = b(t), i = y(new TextEncoder().encode("svGo"), n), a = x(e), o = a.length - 12;
121
+ return u(a.slice(0, o), r, i, a.slice(o));
122
+ }
123
+ function C(n) {
124
+ return `<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
125
+ <x:xmpmeta xmlns:x="adobe:ns:meta/">
126
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
127
+ <rdf:Description rdf:about=""
128
+ xmlns:${e}="${t}">
129
+ <${e}:tags>${JSON.stringify(n)}</${e}:tags>
130
+ </rdf:Description>
131
+ </rdf:RDF>
132
+ </x:xmpmeta>
133
+ <?xpacket end="w"?>`;
134
+ }
135
+ function w(e, t) {
136
+ if (!t || Object.keys(t).length === 0) return e;
137
+ let n = b(new TextEncoder().encode(C(t))), r = x(e), i = r.length - 12;
138
+ return u(r.slice(0, i), n, r.slice(i));
139
+ }
140
+ var T = [
141
+ "source",
142
+ "screen",
143
+ "capturedAt",
144
+ "commit"
145
+ ];
146
+ function E(e) {
147
+ let t = a(e.annotationsSvg, e.width, e.height, e.tags), n = new TextEncoder().encode(t), r = typeof e.originalImage == "string" ? f(e.originalImage) : e.originalImage;
148
+ return S(e.renderedPng, n, r);
149
+ }
150
+ function D(e) {
151
+ return A(e) ? M(e) : null;
152
+ }
153
+ function O(e) {
154
+ return k(e) ? j(e) : A(e) ? M(e) : null;
155
+ }
156
+ function k(e) {
157
+ return e[0] === 255 && e[1] === 216;
158
+ }
159
+ function A(e) {
160
+ return e[0] === 137 && e[1] === 80 && e[2] === 78 && e[3] === 71;
161
+ }
162
+ function j(e) {
163
+ let t = F(e), n = I(e);
164
+ return t ? N(t, n) : null;
165
+ }
166
+ function M(e) {
167
+ let t = L(e), n = R(e);
168
+ return t ? N(t, n) : null;
169
+ }
170
+ function N(e, t) {
171
+ let n = P(e, "annotations");
172
+ if (!n) return null;
173
+ let r = n.replace(/^<!\[CDATA\[/, "").replace(/\]\]>$/, ""), i = Number.parseInt(P(e, "width") || "0", 10), a = Number.parseInt(P(e, "height") || "0", 10), o = "";
174
+ t && t.length > 0 && (o = `data:${t[0] === 137 && t[1] === 80 ? "image/png" : "image/jpeg"};base64,${z(t)}`);
175
+ let s = {}, c = P(e, "tags");
176
+ if (c) try {
177
+ s = JSON.parse(c);
178
+ } catch {}
179
+ return {
180
+ originalImageDataUrl: o,
181
+ annotationsSvg: r,
182
+ width: i,
183
+ height: a,
184
+ tags: s
185
+ };
186
+ }
187
+ function P(t, n) {
188
+ let r = `<${e}:${n}>`, i = `</${e}:${n}>`, a = t.indexOf(r);
189
+ if (a < 0) return null;
190
+ let o = t.indexOf(i, a);
191
+ return o < 0 ? null : t.substring(a + r.length, o);
192
+ }
193
+ function F(e) {
194
+ let t = 2;
195
+ for (; t + 4 <= e.length && e[t] === 255;) {
196
+ let r = e[t + 1];
197
+ if (r === 217 || r === 218) break;
198
+ let i = c(e, t + 2), a = t + 2 + i;
199
+ if (a > e.length) break;
200
+ if (r === 225 && d(e, t + 4, n)) {
201
+ let r = t + 4 + n.length;
202
+ return new TextDecoder().decode(e.slice(r, a));
203
+ }
204
+ t = a;
205
+ }
206
+ return null;
207
+ }
208
+ function I(e) {
209
+ let t = r.length, n = [], i = 2;
210
+ for (; i + 4 <= e.length && e[i] === 255;) {
211
+ let a = e[i + 1];
212
+ if (a === 217 || a === 218) break;
213
+ let o = c(e, i + 2), s = i + 2 + o;
214
+ if (s > e.length) break;
215
+ if (a === 226 && d(e, i + 4, r)) {
216
+ let r = i + 4 + t;
217
+ if (r + 4 <= s) {
218
+ let t = c(e, r), i = e.slice(r + 4, s);
219
+ n.push({
220
+ seq: t,
221
+ data: i
222
+ });
223
+ }
224
+ }
225
+ i = s;
226
+ }
227
+ return n.length === 0 ? null : (n.sort((e, t) => e.seq - t.seq), u(...n.map((e) => e.data)));
228
+ }
229
+ function L(e) {
230
+ let t = 8;
231
+ for (; t + 12 <= e.length;) {
232
+ let n = l(e, t), r = String.fromCharCode(e[t + 4], e[t + 5], e[t + 6], e[t + 7]), a = t + 8, o = a + n + 4;
233
+ if (o > e.length) break;
234
+ if (r === "iTXt" && d(e, a, i)) {
235
+ let t = a + i.length, r = 0, o = t;
236
+ for (let i = t; i < a + n; i++) if (e[i] === 0 && r++, r >= 4) {
237
+ o = i + 1;
238
+ break;
239
+ }
240
+ return new TextDecoder().decode(e.slice(o, a + n));
241
+ }
242
+ t = o;
243
+ }
244
+ return null;
245
+ }
246
+ function R(e) {
247
+ let t = 8;
248
+ for (; t + 12 <= e.length;) {
249
+ let n = l(e, t), r = String.fromCharCode(e[t + 4], e[t + 5], e[t + 6], e[t + 7]), i = t + 8, a = i + n + 4;
250
+ if (a > e.length) break;
251
+ if (r === "svGo") return e.slice(i, i + n);
252
+ t = a;
253
+ }
254
+ return null;
255
+ }
256
+ function z(e) {
257
+ let t = 32768, n = "";
258
+ for (let r = 0; r < e.length; r += t) {
259
+ let i = e.subarray(r, Math.min(r + t, e.length));
260
+ n += String.fromCharCode.apply(null, i);
261
+ }
262
+ return btoa(n);
263
+ }
264
+ //#endregion
265
+ export { T as WELL_KNOWN_TAG_KEYS, a as buildXmp, C as buildXmpTagsOnly, E as createEditablePngBytes, f as dataUrlToUint8Array, O as readEditableImage, D as readEditablePngBytes, g as writeJpegWithMetadata, S as writePngWithMetadata, w as writePngWithTagsOnly };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ingcreators/annot-core",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Annot SDK — SVG-first screenshot annotation format, storage abstractions, and editor primitives. The foundation shared by the PWA, Chrome extension, Electron desktop, VSCode extension, and the headless annotator.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "ingcreators",
@@ -30,6 +30,10 @@
30
30
  "types": "./dist/index.d.ts",
31
31
  "default": "./dist/index.js"
32
32
  },
33
+ "./xmp-bytes": {
34
+ "types": "./dist/xmp/xmp-bytes.d.ts",
35
+ "default": "./dist/xmp-bytes.js"
36
+ },
33
37
  "./styles/*": "./styles/*"
34
38
  },
35
39
  "files": [
package/styles/editor.css CHANGED
@@ -179,9 +179,12 @@ body {
179
179
 
180
180
  /* The contentEditable overlay lives inside a `<foreignObject>` —
181
181
  bring text selection back so the user can mark / replace runs
182
- while editing. */
183
- #svg-root foreignObject [contenteditable="true"],
184
- [data-annot-shell-root] foreignObject [contenteditable="true"] {
182
+ while editing. Selectors ordered ascending-by-specificity so
183
+ Biome's `noDescendingSpecificity` rule is satisfied:
184
+ `[data-annot-shell-root]` is (0,2,1); `#svg-root` is (1,1,1).
185
+ Same applied rules either way. */
186
+ [data-annot-shell-root] foreignObject [contenteditable="true"],
187
+ #svg-root foreignObject [contenteditable="true"] {
185
188
  user-select: text;
186
189
  -webkit-user-select: text;
187
190
  }