@w100n/documents 0.3.0 → 0.10.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.
Files changed (55) hide show
  1. package/dist/SheetView-3XTEV2VT.css +319 -0
  2. package/dist/SheetView-3XTEV2VT.css.map +1 -0
  3. package/dist/SheetView-JYH2ZUZF.js +928 -0
  4. package/dist/SheetView-JYH2ZUZF.js.map +1 -0
  5. package/dist/TextEditor-X3X62R46.js +982 -0
  6. package/dist/TextEditor-X3X62R46.js.map +1 -0
  7. package/dist/caveat-cyrillic-XVO43JCM.woff2 +0 -0
  8. package/dist/caveat-latin-IUBKKMHQ.woff2 +0 -0
  9. package/dist/caveat-latin-ext-5S7R5SZN.woff2 +0 -0
  10. package/dist/chunk-CE3AADY6.js +3447 -0
  11. package/dist/chunk-CE3AADY6.js.map +1 -0
  12. package/dist/chunk-ISOOUYLI.js +150 -0
  13. package/dist/chunk-ISOOUYLI.js.map +1 -0
  14. package/dist/{chunk-KEV4R7W5.js → chunk-K364NAYP.js} +4 -1
  15. package/dist/chunk-K364NAYP.js.map +1 -0
  16. package/dist/chunk-QDH7EZAF.js +27 -0
  17. package/dist/chunk-QDH7EZAF.js.map +1 -0
  18. package/dist/chunk-SVRYWMES.js +196 -0
  19. package/dist/chunk-SVRYWMES.js.map +1 -0
  20. package/dist/chunk-TDP6OJET.js +31 -0
  21. package/dist/chunk-TDP6OJET.js.map +1 -0
  22. package/dist/chunk-TNSN4ZQ5.js +2909 -0
  23. package/dist/chunk-TNSN4ZQ5.js.map +1 -0
  24. package/dist/collab.cjs +6312 -0
  25. package/dist/collab.cjs.map +1 -0
  26. package/dist/collab.d.cts +39 -0
  27. package/dist/collab.d.ts +39 -0
  28. package/dist/collab.js +30 -0
  29. package/dist/collab.js.map +1 -0
  30. package/dist/grid-EI5JNZAA.js +88 -0
  31. package/dist/grid-EI5JNZAA.js.map +1 -0
  32. package/dist/index.cjs +12265 -407
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.css +3448 -214
  35. package/dist/index.css.map +1 -1
  36. package/dist/index.d.cts +145 -7
  37. package/dist/index.d.ts +145 -7
  38. package/dist/index.js +3469 -340
  39. package/dist/index.js.map +1 -1
  40. package/dist/memory.cjs +59 -7
  41. package/dist/memory.cjs.map +1 -1
  42. package/dist/memory.d.cts +7 -2
  43. package/dist/memory.d.ts +7 -2
  44. package/dist/memory.js +57 -8
  45. package/dist/memory.js.map +1 -1
  46. package/dist/pdfWrite-EM6GJDBF.js +76 -0
  47. package/dist/pdfWrite-EM6GJDBF.js.map +1 -0
  48. package/dist/types-B5oF25dn.d.cts +165 -0
  49. package/dist/types-B5oF25dn.d.ts +165 -0
  50. package/dist/write-DaVtTJCS.d.cts +6 -0
  51. package/dist/write-DaVtTJCS.d.ts +6 -0
  52. package/package.json +45 -3
  53. package/dist/chunk-KEV4R7W5.js.map +0 -1
  54. package/dist/types-DiEpNWSu.d.cts +0 -59
  55. package/dist/types-DiEpNWSu.d.ts +0 -59
@@ -0,0 +1,150 @@
1
+ 'use client';
2
+
3
+ // src/sheets/refs.ts
4
+ var MAX_ROW = 1048575;
5
+ var MAX_COL = 16383;
6
+ function letters(c) {
7
+ let s = "";
8
+ for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
9
+ return s;
10
+ }
11
+ function column(s) {
12
+ let n = 0;
13
+ for (let i = 0; i < s.length; i++) n = n * 26 + (s.charCodeAt(i) & ~32) - 64;
14
+ return n - 1;
15
+ }
16
+ var a1 = (r, c) => letters(c) + (r + 1);
17
+ function cell(ref) {
18
+ const m = /^\$?([A-Za-z]{1,3})\$?(\d+)$/.exec(ref);
19
+ return m ? [Number(m[2]) - 1, column(m[1])] : [-1, -1];
20
+ }
21
+ function side(s) {
22
+ const m = /^(\$?)([A-Za-z]{1,3})?(\$?)(\d+)?$/.exec(s);
23
+ if (!m || !m[2] && !m[4]) return null;
24
+ return {
25
+ col: m[2] ? column(m[2]) : null,
26
+ row: m[4] ? Number(m[4]) - 1 : null,
27
+ colAbs: !!m[2] && m[1] === "$",
28
+ rowAbs: m[2] ? m[3] === "$" : m[1] === "$" || m[3] === "$"
29
+ };
30
+ }
31
+ var write = (s) => (s.col === null ? "" : (s.colAbs ? "$" : "") + letters(s.col)) + (s.row === null ? "" : (s.rowAbs ? "$" : "") + (s.row + 1));
32
+ function box(ref) {
33
+ const [a, b = a] = ref.split(":");
34
+ const p = side(a), q = side(b);
35
+ if (!p || !q) return null;
36
+ const rows = [p.row ?? (p === q ? 0 : 0), q.row ?? MAX_ROW], cols = [p.col ?? 0, q.col ?? MAX_COL];
37
+ return { startRow: Math.min(rows[0], rows[1]), endRow: Math.max(rows[0], rows[1]), startColumn: Math.min(cols[0], cols[1]), endColumn: Math.max(cols[0], cols[1]) };
38
+ }
39
+ var span = (b) => b.startRow === b.endRow && b.startColumn === b.endColumn ? a1(b.startRow, b.startColumn) : `${a1(b.startRow, b.startColumn)}:${a1(b.endRow, b.endColumn)}`;
40
+ function boxes(sqref) {
41
+ return sqref.trim().split(/\s+/).filter(Boolean).map(box).filter((b) => b !== null);
42
+ }
43
+ function squeeze(b, rows, cols) {
44
+ const edge = (from, to, map, max) => {
45
+ if (from === 0 && to === max) return [0, max];
46
+ let a = -1, z = -1;
47
+ for (let i = from; i <= to && a < 0; i++) a = map(i);
48
+ for (let i = to; i >= from && z < 0; i--) z = map(i);
49
+ return a < 0 || z < 0 ? null : [a, z];
50
+ };
51
+ const r = edge(b.startRow, b.endRow, rows, MAX_ROW), c = edge(b.startColumn, b.endColumn, cols, MAX_COL);
52
+ return r && c ? { startRow: r[0], endRow: r[1], startColumn: c[0], endColumn: c[1] } : null;
53
+ }
54
+ var token = /("(?:[^"]|"")*")|('(?:[^']|'')+'|[A-Za-z_À-￿][\w.À-￿]*)!|(\[(?:[^[\]]|\[[^\]]*\])*\])|(\$?[A-Za-z]{1,3}\$?\d+(?::\$?[A-Za-z]{1,3}\$?\d+)?|\$?[A-Za-z]{1,3}:\$?[A-Za-z]{1,3}|\$?\d+:\$?\d+)(?![\w(.!À-￿])/g;
55
+ function refs(formula, visit) {
56
+ let sheet = null;
57
+ let outside = false;
58
+ let last = 0;
59
+ let out = "";
60
+ token.lastIndex = 0;
61
+ for (let m = token.exec(formula); m; m = token.exec(formula)) {
62
+ if (m[1]) {
63
+ sheet = null;
64
+ continue;
65
+ }
66
+ if (m[3]) {
67
+ outside = formula[m.index - 1] !== "!" && /^\[\d+\]$/.test(m[3]);
68
+ continue;
69
+ }
70
+ if (m[2]) {
71
+ sheet = outside ? "\0" : m[2].startsWith("'") ? m[2].slice(1, -1).replace(/''/g, "'") : m[2];
72
+ outside = false;
73
+ continue;
74
+ }
75
+ const before = formula[m.index - 1];
76
+ if (before && /[\w.À-￿]/.test(before)) {
77
+ sheet = null;
78
+ continue;
79
+ }
80
+ out += formula.slice(last, m.index) + visit({ sheet: before === "!" ? sheet : null, text: m[4] });
81
+ last = m.index + m[0].length;
82
+ sheet = null;
83
+ }
84
+ return out + formula.slice(last);
85
+ }
86
+ function shifted(formula, dr, dc) {
87
+ return refs(formula, (p) => {
88
+ const ends = p.text.split(":").map(side);
89
+ if (ends.some((e) => !e)) return p.text;
90
+ for (const e of ends) {
91
+ if (e.col !== null && !e.colAbs) e.col += dc;
92
+ if (e.row !== null && !e.rowAbs) e.row += dr;
93
+ if ((e.col ?? 0) < 0 || (e.row ?? 0) < 0 || (e.col ?? 0) > MAX_COL || (e.row ?? 0) > MAX_ROW) return "#REF!";
94
+ }
95
+ return ends.map(write).join(":");
96
+ });
97
+ }
98
+ function remapped(formula, mine, rows, cols) {
99
+ return refs(formula, (p) => {
100
+ if (!mine(p.sheet)) return p.text;
101
+ const b = box(p.text);
102
+ const ends = p.text.split(":").map(side);
103
+ if (!b || ends.some((e) => !e)) return p.text;
104
+ const s = squeeze(b, rows, cols);
105
+ if (!s) return "#REF!";
106
+ const [first, second = first] = ends;
107
+ const put = (e, r, c) => ({ ...e, row: e.row === null ? null : r, col: e.col === null ? null : c });
108
+ return ends.length === 1 ? write(put(first, s.startRow, s.startColumn)) : `${write(put(first, s.startRow, s.startColumn))}:${write(put(second, s.endRow, s.endColumn))}`;
109
+ });
110
+ }
111
+ var quoted = (name) => /^[A-Za-z_À-￿][\w.À-￿]*$/.test(name) && !/^[A-Za-z]{1,3}\d+$/.test(name) && !/^(R|C|RC|R\d+C\d+)$/i.test(name) ? name : `'${name.replace(/'/g, "''")}'`;
112
+ function renamed(formula, from, to) {
113
+ token.lastIndex = 0;
114
+ return formula.replace(token, (all, str, sheet) => {
115
+ if (str || !sheet) return all;
116
+ const name = sheet.startsWith("'") ? sheet.slice(1, -1).replace(/''/g, "'") : sheet;
117
+ return name === from ? `${quoted(to)}!` : all;
118
+ });
119
+ }
120
+ var future = "ACOT ACOTH AGGREGATE ARABIC ARRAYTOTEXT BASE BETA.DIST BETA.INV BINOM.DIST BINOM.DIST.RANGE BINOM.INV BITAND BITLSHIFT BITOR BITRSHIFT BITXOR BYCOL BYROW CEILING.MATH CEILING.PRECISE CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CHOOSECOLS CHOOSEROWS COMBINA CONCAT CONFIDENCE.NORM CONFIDENCE.T COT COTH COVARIANCE.P COVARIANCE.S CSC CSCH DAYS DECIMAL DROP ERF.PRECISE ERFC.PRECISE EXPAND EXPON.DIST F.DIST F.DIST.RT F.INV F.INV.RT F.TEST FILTERXML FLOOR.MATH FLOOR.PRECISE FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR FORMULATEXT GAMMA GAMMA.DIST GAMMA.INV GAMMALN.PRECISE GAUSS HSTACK HYPGEOM.DIST IFNA IFS IMCOSH IMCOT IMCSC IMCSCH IMSEC IMSECH IMSINH IMTAN ISFORMULA ISOMITTED ISOWEEKNUM LAMBDA LET LOGNORM.DIST LOGNORM.INV MAKEARRAY MAP MAXIFS MINIFS MODE.MULT MODE.SNGL MUNIT NEGBINOM.DIST NETWORKDAYS.INTL NORM.DIST NORM.INV NORM.S.DIST NORM.S.INV NUMBERVALUE PDURATION PERCENTILE.EXC PERCENTILE.INC PERCENTRANK.EXC PERCENTRANK.INC PERMUTATIONA PHI POISSON.DIST QUARTILE.EXC QUARTILE.INC RANDARRAY RANK.AVG RANK.EQ REDUCE RRI SCAN SEC SECH SEQUENCE SHEET SHEETS SKEW.P STDEV.P STDEV.S SWITCH T.DIST T.DIST.2T T.DIST.RT T.INV T.INV.2T T.TEST TAKE TEXTAFTER TEXTBEFORE TEXTJOIN TEXTSPLIT TOCOL TOROW UNICHAR UNICODE UNIQUE VALUETOTEXT VAR.P VAR.S VSTACK WEBSERVICE WEIBULL.DIST WORKDAY.INTL WRAPCOLS WRAPROWS XLOOKUP XMATCH XOR Z.TEST";
121
+ var prefixes = new Map([...future.split(" ").map((n) => [n, "_xlfn."]), ..."FILTER SORT SORTBY".split(" ").map((n) => [n, "_xlfn._xlws."])]);
122
+ var plain = (formula) => formula.includes("_xl") ? formula.replace(/_xlfn\.(?:_xlws\.)?|_xlws\./gi, "") : formula;
123
+ function stored(formula) {
124
+ let out = "";
125
+ let last = 0;
126
+ const re = /("(?:[^"]|"")*")|((?<![\w.])[A-Za-z][\w.]*)(?=\()/g;
127
+ for (let m = re.exec(formula); m; m = re.exec(formula)) {
128
+ const prefix = m[2] && prefixes.get(m[2].toUpperCase());
129
+ if (!prefix) continue;
130
+ out += formula.slice(last, m.index) + prefix + m[2];
131
+ last = m.index + m[2].length;
132
+ }
133
+ return out + formula.slice(last);
134
+ }
135
+
136
+ export {
137
+ a1,
138
+ cell,
139
+ box,
140
+ span,
141
+ boxes,
142
+ squeeze,
143
+ shifted,
144
+ remapped,
145
+ quoted,
146
+ renamed,
147
+ plain,
148
+ stored
149
+ };
150
+ //# sourceMappingURL=chunk-ISOOUYLI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sheets/refs.ts"],"sourcesContent":["export type Box = { startRow: number; startColumn: number; endRow: number; endColumn: number };\n\nexport type Map1 = (i: number) => number;\n\nconst MAX_ROW = 1048575;\nconst MAX_COL = 16383;\n\nexport function letters(c: number) {\n let s = '';\n for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + ((n - 1) % 26)) + s;\n return s;\n}\n\nexport function column(s: string) {\n let n = 0;\n for (let i = 0; i < s.length; i++) n = n * 26 + (s.charCodeAt(i) & ~32) - 64;\n return n - 1;\n}\n\nexport const a1 = (r: number, c: number) => letters(c) + (r + 1);\n\nexport function cell(ref: string): [number, number] {\n const m = /^\\$?([A-Za-z]{1,3})\\$?(\\d+)$/.exec(ref);\n return m ? [Number(m[2]) - 1, column(m[1])] : [-1, -1];\n}\n\ntype Side = { col: number | null; row: number | null; colAbs: boolean; rowAbs: boolean };\n\nfunction side(s: string): Side | null {\n const m = /^(\\$?)([A-Za-z]{1,3})?(\\$?)(\\d+)?$/.exec(s);\n if (!m || (!m[2] && !m[4])) return null;\n return {\n col: m[2] ? column(m[2]) : null,\n row: m[4] ? Number(m[4]) - 1 : null,\n colAbs: !!m[2] && m[1] === '$',\n rowAbs: m[2] ? m[3] === '$' : m[1] === '$' || m[3] === '$',\n };\n}\n\nconst write = (s: Side) => (s.col === null ? '' : (s.colAbs ? '$' : '') + letters(s.col)) + (s.row === null ? '' : (s.rowAbs ? '$' : '') + (s.row + 1));\n\nexport function box(ref: string): Box | null {\n const [a, b = a] = ref.split(':');\n const p = side(a), q = side(b);\n if (!p || !q) return null;\n const rows = [p.row ?? (p === q ? 0 : 0), q.row ?? MAX_ROW], cols = [p.col ?? 0, q.col ?? MAX_COL];\n return { startRow: Math.min(rows[0], rows[1]), endRow: Math.max(rows[0], rows[1]), startColumn: Math.min(cols[0], cols[1]), endColumn: Math.max(cols[0], cols[1]) };\n}\n\nexport const span = (b: Box) => b.startRow === b.endRow && b.startColumn === b.endColumn ? a1(b.startRow, b.startColumn) : `${a1(b.startRow, b.startColumn)}:${a1(b.endRow, b.endColumn)}`;\n\nexport function boxes(sqref: string) {\n return sqref.trim().split(/\\s+/).filter(Boolean).map(box).filter((b): b is Box => b !== null);\n}\n\nexport function squeeze(b: Box, rows: Map1, cols: Map1): Box | null {\n const edge = (from: number, to: number, map: Map1, max: number): [number, number] | null => {\n if (from === 0 && to === max) return [0, max];\n let a = -1, z = -1;\n for (let i = from; i <= to && a < 0; i++) a = map(i);\n for (let i = to; i >= from && z < 0; i--) z = map(i);\n return a < 0 || z < 0 ? null : [a, z];\n };\n const r = edge(b.startRow, b.endRow, rows, MAX_ROW), c = edge(b.startColumn, b.endColumn, cols, MAX_COL);\n return r && c ? { startRow: r[0], endRow: r[1], startColumn: c[0], endColumn: c[1] } : null;\n}\n\nconst token = /(\"(?:[^\"]|\"\")*\")|('(?:[^']|'')+'|[A-Za-z_À-￿][\\w.À-￿]*)!|(\\[(?:[^[\\]]|\\[[^\\]]*\\])*\\])|(\\$?[A-Za-z]{1,3}\\$?\\d+(?::\\$?[A-Za-z]{1,3}\\$?\\d+)?|\\$?[A-Za-z]{1,3}:\\$?[A-Za-z]{1,3}|\\$?\\d+:\\$?\\d+)(?![\\w(.!À-￿])/g;\n\nexport type Piece = { sheet: string | null; text: string };\n\nexport function refs(formula: string, visit: (piece: Piece) => string): string {\n let sheet: string | null = null;\n let outside = false;\n let last = 0;\n let out = '';\n token.lastIndex = 0;\n for (let m = token.exec(formula); m; m = token.exec(formula)) {\n if (m[1]) { sheet = null; continue; }\n if (m[3]) { outside = formula[m.index - 1] !== '!' && /^\\[\\d+\\]$/.test(m[3]); continue; }\n if (m[2]) {\n sheet = outside ? '\\u0000' : m[2].startsWith(\"'\") ? m[2].slice(1, -1).replace(/''/g, \"'\") : m[2];\n outside = false;\n continue;\n }\n const before = formula[m.index - 1];\n if (before && /[\\w.À-￿]/.test(before)) { sheet = null; continue; }\n out += formula.slice(last, m.index) + visit({ sheet: before === '!' ? sheet : null, text: m[4] });\n last = m.index + m[0].length;\n sheet = null;\n }\n return out + formula.slice(last);\n}\n\nexport function shifted(formula: string, dr: number, dc: number) {\n return refs(formula, p => {\n const ends = p.text.split(':').map(side);\n if (ends.some(e => !e)) return p.text;\n for (const e of ends as Side[]) {\n if (e.col !== null && !e.colAbs) e.col += dc;\n if (e.row !== null && !e.rowAbs) e.row += dr;\n if ((e.col ?? 0) < 0 || (e.row ?? 0) < 0 || (e.col ?? 0) > MAX_COL || (e.row ?? 0) > MAX_ROW) return '#REF!';\n }\n return (ends as Side[]).map(write).join(':');\n });\n}\n\nexport function remapped(formula: string, mine: (sheet: string | null) => boolean, rows: Map1, cols: Map1) {\n return refs(formula, p => {\n if (!mine(p.sheet)) return p.text;\n const b = box(p.text);\n const ends = p.text.split(':').map(side) as Side[];\n if (!b || ends.some(e => !e)) return p.text;\n const s = squeeze(b, rows, cols);\n if (!s) return '#REF!';\n const [first, second = first] = ends;\n const put = (e: Side, r: number, c: number) => ({ ...e, row: e.row === null ? null : r, col: e.col === null ? null : c });\n return ends.length === 1 ? write(put(first, s.startRow, s.startColumn)) : `${write(put(first, s.startRow, s.startColumn))}:${write(put(second, s.endRow, s.endColumn))}`;\n });\n}\n\nexport const quoted = (name: string) => /^[A-Za-z_À-￿][\\w.À-￿]*$/.test(name) && !/^[A-Za-z]{1,3}\\d+$/.test(name) && !/^(R|C|RC|R\\d+C\\d+)$/i.test(name) ? name : `'${name.replace(/'/g, \"''\")}'`;\n\nexport function renamed(formula: string, from: string, to: string) {\n token.lastIndex = 0;\n return formula.replace(token, (all, str: string | undefined, sheet: string | undefined) => {\n if (str || !sheet) return all;\n const name = sheet.startsWith(\"'\") ? sheet.slice(1, -1).replace(/''/g, \"'\") : sheet;\n return name === from ? `${quoted(to)}!` : all;\n });\n}\n\nconst future = 'ACOT ACOTH AGGREGATE ARABIC ARRAYTOTEXT BASE BETA.DIST BETA.INV BINOM.DIST BINOM.DIST.RANGE BINOM.INV BITAND BITLSHIFT BITOR BITRSHIFT BITXOR BYCOL BYROW CEILING.MATH CEILING.PRECISE CHISQ.DIST CHISQ.DIST.RT CHISQ.INV CHISQ.INV.RT CHISQ.TEST CHOOSECOLS CHOOSEROWS COMBINA CONCAT CONFIDENCE.NORM CONFIDENCE.T COT COTH COVARIANCE.P COVARIANCE.S CSC CSCH DAYS DECIMAL DROP ERF.PRECISE ERFC.PRECISE EXPAND EXPON.DIST F.DIST F.DIST.RT F.INV F.INV.RT F.TEST FILTERXML FLOOR.MATH FLOOR.PRECISE FORECAST.ETS FORECAST.ETS.CONFINT FORECAST.ETS.SEASONALITY FORECAST.ETS.STAT FORECAST.LINEAR FORMULATEXT GAMMA GAMMA.DIST GAMMA.INV GAMMALN.PRECISE GAUSS HSTACK HYPGEOM.DIST IFNA IFS IMCOSH IMCOT IMCSC IMCSCH IMSEC IMSECH IMSINH IMTAN ISFORMULA ISOMITTED ISOWEEKNUM LAMBDA LET LOGNORM.DIST LOGNORM.INV MAKEARRAY MAP MAXIFS MINIFS MODE.MULT MODE.SNGL MUNIT NEGBINOM.DIST NETWORKDAYS.INTL NORM.DIST NORM.INV NORM.S.DIST NORM.S.INV NUMBERVALUE PDURATION PERCENTILE.EXC PERCENTILE.INC PERCENTRANK.EXC PERCENTRANK.INC PERMUTATIONA PHI POISSON.DIST QUARTILE.EXC QUARTILE.INC RANDARRAY RANK.AVG RANK.EQ REDUCE RRI SCAN SEC SECH SEQUENCE SHEET SHEETS SKEW.P STDEV.P STDEV.S SWITCH T.DIST T.DIST.2T T.DIST.RT T.INV T.INV.2T T.TEST TAKE TEXTAFTER TEXTBEFORE TEXTJOIN TEXTSPLIT TOCOL TOROW UNICHAR UNICODE UNIQUE VALUETOTEXT VAR.P VAR.S VSTACK WEBSERVICE WEIBULL.DIST WORKDAY.INTL WRAPCOLS WRAPROWS XLOOKUP XMATCH XOR Z.TEST';\nconst prefixes = new Map<string, string>([...future.split(' ').map(n => [n, '_xlfn.'] as const), ...'FILTER SORT SORTBY'.split(' ').map(n => [n, '_xlfn._xlws.'] as const)]);\n\nexport const plain = (formula: string) => formula.includes('_xl') ? formula.replace(/_xlfn\\.(?:_xlws\\.)?|_xlws\\./gi, '') : formula;\n\nexport function stored(formula: string) {\n let out = '';\n let last = 0;\n const re = /(\"(?:[^\"]|\"\")*\")|((?<![\\w.])[A-Za-z][\\w.]*)(?=\\()/g;\n for (let m = re.exec(formula); m; m = re.exec(formula)) {\n const prefix = m[2] && prefixes.get(m[2].toUpperCase());\n if (!prefix) continue;\n out += formula.slice(last, m.index) + prefix + m[2];\n last = m.index + m[2].length;\n }\n return out + formula.slice(last);\n}\n"],"mappings":"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","names":[]}
@@ -8,6 +8,9 @@ var byExtension = {
8
8
  pdf: "pdf",
9
9
  xlsx: "sheet",
10
10
  csv: "sheet",
11
+ xls: "sheet",
12
+ ods: "sheet",
13
+ tsv: "sheet",
11
14
  html: "slides",
12
15
  htm: "slides"
13
16
  };
@@ -34,4 +37,4 @@ export {
34
37
  kindOf,
35
38
  matches
36
39
  };
37
- //# sourceMappingURL=chunk-KEV4R7W5.js.map
40
+ //# sourceMappingURL=chunk-K364NAYP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/kinds.ts"],"sourcesContent":["import type { DocumentKind } from './types';\n\nconst byExtension: Record<string, DocumentKind> = {\n docx: 'docx', md: 'markdown', markdown: 'markdown', pdf: 'pdf', xlsx: 'sheet', csv: 'sheet', xls: 'sheet', ods: 'sheet', tsv: 'sheet', html: 'slides', htm: 'slides',\n};\n\nconst byMime: Record<string, DocumentKind> = {\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'docx',\n 'text/markdown': 'markdown',\n 'application/pdf': 'pdf',\n 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'sheet',\n 'text/csv': 'sheet',\n 'text/html': 'slides',\n};\n\nexport const kinds: DocumentKind[] = ['docx', 'markdown', 'pdf', 'sheet', 'slides'];\n\nexport function kindOf(name: string, mimeType?: string | null): DocumentKind | null {\n const extension = name.includes('.') ? name.split('.').pop()!.toLowerCase() : '';\n return byExtension[extension] ?? (mimeType ? byMime[mimeType.split(';')[0].trim().toLowerCase()] : undefined) ?? null;\n}\n\nexport function matches(doc: { name: string; kind: DocumentKind }, query: string, kind: DocumentKind | 'all') {\n const words = query.toLocaleLowerCase().split(/\\s+/).filter(Boolean);\n return (kind === 'all' || doc.kind === kind) && words.every(word => doc.name.toLocaleLowerCase().includes(word));\n}\n"],"mappings":";;;AAEA,IAAM,cAA4C;AAAA,EAChD,MAAM;AAAA,EAAQ,IAAI;AAAA,EAAY,UAAU;AAAA,EAAY,KAAK;AAAA,EAAO,MAAM;AAAA,EAAS,KAAK;AAAA,EAAS,KAAK;AAAA,EAAS,KAAK;AAAA,EAAS,KAAK;AAAA,EAAS,MAAM;AAAA,EAAU,KAAK;AAC9J;AAEA,IAAM,SAAuC;AAAA,EAC3C,2EAA2E;AAAA,EAC3E,iBAAiB;AAAA,EACjB,mBAAmB;AAAA,EACnB,qEAAqE;AAAA,EACrE,YAAY;AAAA,EACZ,aAAa;AACf;AAEO,IAAM,QAAwB,CAAC,QAAQ,YAAY,OAAO,SAAS,QAAQ;AAE3E,SAAS,OAAO,MAAc,UAA+C;AAClF,QAAM,YAAY,KAAK,SAAS,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,EAAG,YAAY,IAAI;AAC9E,SAAO,YAAY,SAAS,MAAM,WAAW,OAAO,SAAS,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,IAAI,WAAc;AACnH;AAEO,SAAS,QAAQ,KAA2C,OAAe,MAA4B;AAC5G,QAAM,QAAQ,MAAM,kBAAkB,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO;AACnE,UAAQ,SAAS,SAAS,IAAI,SAAS,SAAS,MAAM,MAAM,UAAQ,IAAI,KAAK,kBAAkB,EAAE,SAAS,IAAI,CAAC;AACjH;","names":[]}
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+
3
+ // src/useLoad.ts
4
+ import { useEffect, useState } from "react";
5
+ function useLoad(load, key) {
6
+ const [state, setState] = useState({ data: null, error: null, loading: true });
7
+ const [attempt, setAttempt] = useState(0);
8
+ useEffect(() => {
9
+ const controller = new AbortController();
10
+ setState((current) => ({ ...current, loading: true, error: null }));
11
+ load(controller.signal).then(
12
+ (data) => {
13
+ if (!controller.signal.aborted) setState({ data, error: null, loading: false });
14
+ },
15
+ (error) => {
16
+ if (!controller.signal.aborted) setState({ data: null, error: error instanceof Error ? error : new Error(String(error)), loading: false });
17
+ }
18
+ );
19
+ return () => controller.abort();
20
+ }, [...key, attempt]);
21
+ return { ...state, retry: () => setAttempt((n) => n + 1) };
22
+ }
23
+
24
+ export {
25
+ useLoad
26
+ };
27
+ //# sourceMappingURL=chunk-QDH7EZAF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useLoad.ts"],"sourcesContent":["import { useEffect, useState } from 'react';\n\nexport type Loaded<T> = { data: T | null; error: Error | null; loading: boolean; retry: () => void };\n\nexport function useLoad<T>(load: (signal: AbortSignal) => Promise<T>, key: unknown[]): Loaded<T> {\n const [state, setState] = useState<{ data: T | null; error: Error | null; loading: boolean }>({ data: null, error: null, loading: true });\n const [attempt, setAttempt] = useState(0);\n useEffect(() => {\n const controller = new AbortController();\n setState(current => ({ ...current, loading: true, error: null }));\n load(controller.signal).then(\n data => { if (!controller.signal.aborted) setState({ data, error: null, loading: false }); },\n error => { if (!controller.signal.aborted) setState({ data: null, error: error instanceof Error ? error : new Error(String(error)), loading: false }); },\n );\n return () => controller.abort();\n }, [...key, attempt]);\n return { ...state, retry: () => setAttempt(n => n + 1) };\n}\n"],"mappings":";;;AAAA,SAAS,WAAW,gBAAgB;AAI7B,SAAS,QAAW,MAA2C,KAA2B;AAC/F,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAoE,EAAE,MAAM,MAAM,OAAO,MAAM,SAAS,KAAK,CAAC;AACxI,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,CAAC;AACxC,YAAU,MAAM;AACd,UAAM,aAAa,IAAI,gBAAgB;AACvC,aAAS,cAAY,EAAE,GAAG,SAAS,SAAS,MAAM,OAAO,KAAK,EAAE;AAChE,SAAK,WAAW,MAAM,EAAE;AAAA,MACtB,UAAQ;AAAE,YAAI,CAAC,WAAW,OAAO,QAAS,UAAS,EAAE,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC;AAAA,MAAG;AAAA,MAC3F,WAAS;AAAE,YAAI,CAAC,WAAW,OAAO,QAAS,UAAS,EAAE,MAAM,MAAM,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,GAAG,SAAS,MAAM,CAAC;AAAA,MAAG;AAAA,IACzJ;AACA,WAAO,MAAM,WAAW,MAAM;AAAA,EAChC,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC;AACpB,SAAO,EAAE,GAAG,OAAO,OAAO,MAAM,WAAW,OAAK,IAAI,CAAC,EAAE;AACzD;","names":[]}
@@ -0,0 +1,196 @@
1
+ 'use client';
2
+ import {
3
+ filled,
4
+ follow,
5
+ pending,
6
+ save,
7
+ seed
8
+ } from "./chunk-CE3AADY6.js";
9
+
10
+ // src/editor/live.ts
11
+ import { HocuspocusProvider } from "@hocuspocus/provider";
12
+ import { useEffect, useRef, useState } from "react";
13
+ import * as Y2 from "yjs";
14
+
15
+ // src/room.ts
16
+ import { applyAwarenessUpdate, Awareness, encodeAwarenessUpdate, removeAwarenessStates } from "y-protocols/awareness";
17
+ import * as Y from "yjs";
18
+ var rooms = /* @__PURE__ */ new Map();
19
+ var Link = class {
20
+ constructor(key, id, kind, document, host, author, edit) {
21
+ this.id = id;
22
+ this.kind = kind;
23
+ this.document = document;
24
+ this.host = host;
25
+ this.author = author;
26
+ this.isSynced = false;
27
+ this.unsyncedChanges = 0;
28
+ this.live = false;
29
+ this.events = /* @__PURE__ */ new Map();
30
+ this.peers = () => [...this.room.links].filter((l) => l !== this && l.live);
31
+ this.local = (update, origin) => {
32
+ if (this.live && origin !== this.room && this.authorizedScope === "read-write") Y.applyUpdate(this.room.doc, update, this);
33
+ };
34
+ this.remote = (update, origin) => {
35
+ if (this.live && origin !== this) Y.applyUpdate(this.document, update, this.room);
36
+ };
37
+ this.presence = ({ added, updated, removed }, origin) => {
38
+ if (!this.live || origin === this.room) return;
39
+ const update = encodeAwarenessUpdate(this.awareness, [...added, ...updated, ...removed]);
40
+ for (const peer of this.peers()) applyAwarenessUpdate(peer.awareness, update, this.room);
41
+ };
42
+ this.awareness = new Awareness(document);
43
+ this.authorizedScope = edit ? "read-write" : "readonly";
44
+ if (!rooms.has(key)) rooms.set(key, { doc: new Y.Doc(), links: /* @__PURE__ */ new Set(), base: null, busy: Promise.resolve() });
45
+ this.room = rooms.get(key);
46
+ this.room.links.add(this);
47
+ this.stop = follow(this.room.doc, (origin) => origin === this && edit ? this.author : null);
48
+ document.on("update", this.local);
49
+ this.awareness.on("update", this.presence);
50
+ this.room.doc.on("update", this.remote);
51
+ queueMicrotask(() => this.online(true));
52
+ }
53
+ on(name, fn) {
54
+ if (!this.events.has(name)) this.events.set(name, /* @__PURE__ */ new Set());
55
+ this.events.get(name).add(fn);
56
+ }
57
+ off(name, fn) {
58
+ this.events.get(name)?.delete(fn);
59
+ }
60
+ emit(name, payload) {
61
+ this.events.get(name)?.forEach((fn) => fn(payload));
62
+ }
63
+ online(on) {
64
+ if (on === this.live || !this.room.links.has(this)) return;
65
+ this.live = on;
66
+ if (on) {
67
+ Y.applyUpdate(this.document, Y.encodeStateAsUpdate(this.room.doc, Y.encodeStateVector(this.document)), this.room);
68
+ if (this.authorizedScope === "read-write") Y.applyUpdate(this.room.doc, Y.encodeStateAsUpdate(this.document, Y.encodeStateVector(this.room.doc)), this);
69
+ for (const peer of this.peers()) {
70
+ applyAwarenessUpdate(this.awareness, encodeAwarenessUpdate(peer.awareness, [peer.awareness.clientID]), this.room);
71
+ applyAwarenessUpdate(peer.awareness, encodeAwarenessUpdate(this.awareness, [this.awareness.clientID]), this.room);
72
+ }
73
+ this.isSynced = true;
74
+ } else for (const peer of this.peers()) removeAwarenessStates(peer.awareness, [this.awareness.clientID], this.room);
75
+ this.emit("status", { status: on ? "connected" : "disconnected" });
76
+ if (on) this.emit("synced", { state: true });
77
+ }
78
+ store() {
79
+ const room = this.room;
80
+ const run = room.busy.then(async () => {
81
+ const done = await save(room.doc, this.kind, room.base ?? await this.host.content(this.id), async (bytes, note) => (await this.host.save(this.id, bytes, note)).versionId);
82
+ if (done) room.base = done.bytes;
83
+ return done;
84
+ });
85
+ room.busy = run.catch(() => null);
86
+ return run;
87
+ }
88
+ sendStateless(payload) {
89
+ if (!this.live || this.authorizedScope !== "read-write" || !JSON.parse(payload).save) return;
90
+ this.store().then(
91
+ (done) => this.emit("stateless", { payload: JSON.stringify({ saved: done?.version ?? null }) }),
92
+ () => this.emit("stateless", { payload: JSON.stringify({ failed: true }) })
93
+ );
94
+ }
95
+ destroy() {
96
+ this.online(false);
97
+ this.room.links.delete(this);
98
+ this.stop();
99
+ this.document.off("update", this.local);
100
+ this.awareness.off("update", this.presence);
101
+ this.room.doc.off("update", this.remote);
102
+ this.awareness.destroy();
103
+ if (!this.room.links.size && pending(this.room.doc) && this.authorizedScope === "read-write") this.store().catch(() => null);
104
+ }
105
+ };
106
+
107
+ // src/editor/live.ts
108
+ var colors = ["#1d4ed8", "#be185d", "#15803d", "#c2410c", "#6d28d9", "#0e7490", "#a16207", "#b91c1c"];
109
+ var colorOf = (id) => colors[[...id].reduce((h, c) => Math.imul(h, 31) + c.charCodeAt(0) >>> 0, 7) % colors.length];
110
+ var idle = { synced: false, ready: false, online: false, late: false, denied: false, readonly: false, people: [], pending: false, unsynced: false };
111
+ function useLive(host, id, kind, bytes, json, language, edit, onSaved) {
112
+ const url = host?.collab?.url;
113
+ const owner = useRef(host);
114
+ const [wire, setWire] = useState(null);
115
+ const [state, setState] = useState(idle);
116
+ const waiting = useRef(null);
117
+ const saved = useRef(onSaved);
118
+ useEffect(() => {
119
+ owner.current = host;
120
+ saved.current = onSaved;
121
+ });
122
+ useEffect(() => {
123
+ const host2 = owner.current;
124
+ if (!host2?.collab || !url) return;
125
+ const doc = new Y2.Doc();
126
+ const me = host2.me;
127
+ const user = { id: me.id, name: me.name, avatar: me.avatarUrl ?? "", color: colorOf(me.id) };
128
+ const wire2 = new URL(url, location.href);
129
+ wire2.protocol = wire2.protocol.replace("http", "ws");
130
+ wire2.searchParams.set("lang", language);
131
+ const link = url.startsWith("memory:") ? new Link(`${url}
132
+ ${id}`, id, kind, doc, host2, { id: me.id, name: me.name, language }, edit) : new HocuspocusProvider({ url: wire2.href, name: id, document: doc, token: () => owner.current.collab.token() });
133
+ const set = (next) => setState((s) => ({ ...s, ...next }));
134
+ const editors = doc.getMap("editors");
135
+ const meta = doc.getMap("meta");
136
+ const people = () => {
137
+ const seen = /* @__PURE__ */ new Map();
138
+ link.awareness?.getStates().forEach((s, client) => {
139
+ const u = s.user;
140
+ if (u?.id && u.name && !seen.has(u.id)) seen.set(u.id, { id: u.id, name: u.name, avatarUrl: u.avatar || null, color: u.color ?? colorOf(u.id), me: client === doc.clientID, selection: s.selection });
141
+ });
142
+ set({ people: [...seen.values()] });
143
+ };
144
+ const on = (name, fn) => link.on(name, fn);
145
+ on("synced", ({ state: state2 }) => {
146
+ if (state2) set({ synced: true, online: true });
147
+ });
148
+ on("status", ({ status }) => set({ online: status === "connected" && link.isSynced }));
149
+ on("authenticated", ({ scope }) => set({ readonly: scope === "readonly" }));
150
+ on("authenticationFailed", () => set({ denied: true }));
151
+ on("unsyncedChanges", ({ number }) => set({ unsynced: number > 0 }));
152
+ on("stateless", ({ payload }) => {
153
+ const reply = JSON.parse(payload);
154
+ if (!("saved" in reply) && !reply.failed) return;
155
+ waiting.current?.(!reply.failed);
156
+ waiting.current = null;
157
+ });
158
+ link.awareness?.on("change", people);
159
+ editors.observe(() => set({ pending: editors.size > 0 }));
160
+ meta.observe((e) => {
161
+ if (e.keysChanged.has("version")) saved.current?.();
162
+ });
163
+ const late = setTimeout(() => set({ late: true }), 4e3);
164
+ setWire({ doc, link, user });
165
+ return () => {
166
+ clearTimeout(late);
167
+ waiting.current?.(false);
168
+ link.destroy();
169
+ doc.destroy();
170
+ setWire(null);
171
+ setState(idle);
172
+ };
173
+ }, [url, id, kind, edit, language]);
174
+ useEffect(() => {
175
+ if (!wire || !state.synced || state.ready) return;
176
+ if (filled(wire.doc) || (json || kind === "xlsx" || kind === "csv") && seed(wire.doc, kind, bytes, json)) setState((s) => ({ ...s, ready: true }));
177
+ }, [wire, state.synced, state.ready, json, bytes, kind]);
178
+ const save2 = () => new Promise((done) => {
179
+ if (!wire) return done(false);
180
+ waiting.current?.(false);
181
+ waiting.current = done;
182
+ wire.link.sendStateless(JSON.stringify({ save: true }));
183
+ setTimeout(() => {
184
+ if (waiting.current === done) {
185
+ waiting.current = null;
186
+ done(false);
187
+ }
188
+ }, 3e4);
189
+ });
190
+ return url ? { ...state, wire, save: save2 } : null;
191
+ }
192
+
193
+ export {
194
+ useLive
195
+ };
196
+ //# sourceMappingURL=chunk-SVRYWMES.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/editor/live.ts","../src/room.ts"],"sourcesContent":["import { HocuspocusProvider } from '@hocuspocus/provider';\nimport type { JSONContent } from '@tiptap/core';\nimport { useEffect, useRef, useState } from 'react';\nimport type { Awareness } from 'y-protocols/awareness';\nimport * as Y from 'yjs';\nimport { filled, seed, type Kind } from '../collab';\nimport { Link } from '../room';\nimport type { DocumentsHost, Language, Person } from '../types';\n\ntype Peer = Person & { color: string; me: boolean; selection?: { sheet: string; range: string } };\n\ntype Wire = {\n awareness: Awareness | null;\n isSynced: boolean;\n unsyncedChanges: number;\n on(name: string, fn: (payload: never) => void): unknown;\n off(name: string, fn: (payload: never) => void): unknown;\n sendStateless(payload: string): void;\n destroy(): void;\n};\n\ntype State = { synced: boolean; ready: boolean; online: boolean; late: boolean; denied: boolean; readonly: boolean; people: Peer[]; pending: boolean; unsynced: boolean };\n\nconst colors = ['#1d4ed8', '#be185d', '#15803d', '#c2410c', '#6d28d9', '#0e7490', '#a16207', '#b91c1c'];\nconst colorOf = (id: string) => colors[[...id].reduce((h, c) => (Math.imul(h, 31) + c.charCodeAt(0)) >>> 0, 7) % colors.length];\n\nconst idle: State = { synced: false, ready: false, online: false, late: false, denied: false, readonly: false, people: [], pending: false, unsynced: false };\n\nexport function useLive(host: DocumentsHost | undefined, id: string, kind: Kind, bytes: ArrayBuffer, json: JSONContent | undefined, language: Language, edit: boolean, onSaved?: () => void) {\n const url = host?.collab?.url;\n const owner = useRef(host);\n const [wire, setWire] = useState<{ doc: Y.Doc; link: Wire; user: Record<string, string> } | null>(null);\n const [state, setState] = useState(idle);\n const waiting = useRef<((ok: boolean) => void) | null>(null);\n const saved = useRef(onSaved);\n\n useEffect(() => {\n owner.current = host;\n saved.current = onSaved;\n });\n\n useEffect(() => {\n const host = owner.current;\n if (!host?.collab || !url) return;\n const doc = new Y.Doc();\n const me = host.me;\n const user = { id: me.id, name: me.name, avatar: me.avatarUrl ?? '', color: colorOf(me.id) };\n const wire = new URL(url, location.href);\n wire.protocol = wire.protocol.replace('http', 'ws');\n wire.searchParams.set('lang', language);\n const link: Wire = url.startsWith('memory:')\n ? new Link(`${url}\\n${id}`, id, kind, doc, host, { id: me.id, name: me.name, language }, edit)\n : new HocuspocusProvider({ url: wire.href, name: id, document: doc, token: () => owner.current!.collab!.token() });\n const set = (next: Partial<State>) => setState(s => ({ ...s, ...next }));\n const editors = doc.getMap('editors');\n const meta = doc.getMap('meta');\n const people = () => {\n const seen = new Map<string, Peer>();\n link.awareness?.getStates().forEach((s, client) => {\n const u = s.user as { id?: string; name?: string; avatar?: string; color?: string } | undefined;\n if (u?.id && u.name && !seen.has(u.id)) seen.set(u.id, { id: u.id, name: u.name, avatarUrl: u.avatar || null, color: u.color ?? colorOf(u.id), me: client === doc.clientID, selection: s.selection });\n });\n set({ people: [...seen.values()] });\n };\n const on = <T,>(name: string, fn: (payload: T) => void) => link.on(name, fn as (payload: never) => void);\n on<{ state: boolean }>('synced', ({ state }) => { if (state) set({ synced: true, online: true }); });\n on<{ status: string }>('status', ({ status }) => set({ online: status === 'connected' && link.isSynced }));\n on<{ scope: string }>('authenticated', ({ scope }) => set({ readonly: scope === 'readonly' }));\n on('authenticationFailed', () => set({ denied: true }));\n on<{ number: number }>('unsyncedChanges', ({ number }) => set({ unsynced: number > 0 }));\n on<{ payload: string }>('stateless', ({ payload }) => {\n const reply = JSON.parse(payload) as { saved?: string | null; failed?: boolean };\n if (!('saved' in reply) && !reply.failed) return;\n waiting.current?.(!reply.failed);\n waiting.current = null;\n });\n link.awareness?.on('change', people);\n editors.observe(() => set({ pending: editors.size > 0 }));\n meta.observe(e => { if (e.keysChanged.has('version')) saved.current?.(); });\n const late = setTimeout(() => set({ late: true }), 4000);\n setWire({ doc, link, user });\n return () => {\n clearTimeout(late);\n waiting.current?.(false);\n link.destroy();\n doc.destroy();\n setWire(null);\n setState(idle);\n };\n }, [url, id, kind, edit, language]);\n\n useEffect(() => {\n if (!wire || !state.synced || state.ready) return;\n if (filled(wire.doc) || ((json || kind === 'xlsx' || kind === 'csv') && seed(wire.doc, kind, bytes, json))) setState(s => ({ ...s, ready: true }));\n }, [wire, state.synced, state.ready, json, bytes, kind]);\n\n const save = () => new Promise<boolean>(done => {\n if (!wire) return done(false);\n waiting.current?.(false);\n waiting.current = done;\n wire.link.sendStateless(JSON.stringify({ save: true }));\n setTimeout(() => { if (waiting.current === done) { waiting.current = null; done(false); } }, 30000);\n });\n\n return url ? { ...state, wire, save } : null;\n}\n","import { applyAwarenessUpdate, Awareness, encodeAwarenessUpdate, removeAwarenessStates } from 'y-protocols/awareness';\nimport * as Y from 'yjs';\nimport { follow, pending, save, type Author, type Kind } from './collab';\nimport type { DocumentsHost } from './types';\n\ntype Room = { doc: Y.Doc; links: Set<Link>; base: ArrayBuffer | null; busy: Promise<unknown> };\ntype Listener = (payload: never) => void;\n\nexport const rooms = new Map<string, Room>();\n\nexport class Link {\n awareness: Awareness;\n isSynced = false;\n unsyncedChanges = 0;\n authorizedScope: 'read-write' | 'readonly';\n private room: Room;\n private live = false;\n private stop: () => void;\n private events = new Map<string, Set<Listener>>();\n\n constructor(key: string, private id: string, private kind: Kind, readonly document: Y.Doc, private host: DocumentsHost, readonly author: Author, edit: boolean) {\n this.awareness = new Awareness(document);\n this.authorizedScope = edit ? 'read-write' : 'readonly';\n if (!rooms.has(key)) rooms.set(key, { doc: new Y.Doc(), links: new Set(), base: null, busy: Promise.resolve() });\n this.room = rooms.get(key)!;\n this.room.links.add(this);\n this.stop = follow(this.room.doc, origin => origin === this && edit ? this.author : null);\n document.on('update', this.local);\n this.awareness.on('update', this.presence);\n this.room.doc.on('update', this.remote);\n queueMicrotask(() => this.online(true));\n }\n\n on(name: string, fn: Listener) {\n if (!this.events.has(name)) this.events.set(name, new Set());\n this.events.get(name)!.add(fn);\n }\n\n off(name: string, fn: Listener) {\n this.events.get(name)?.delete(fn);\n }\n\n private emit(name: string, payload: unknown) {\n this.events.get(name)?.forEach(fn => (fn as (p: unknown) => void)(payload));\n }\n\n private peers = () => [...this.room.links].filter(l => l !== this && l.live);\n\n online(on: boolean) {\n if (on === this.live || !this.room.links.has(this)) return;\n this.live = on;\n if (on) {\n Y.applyUpdate(this.document, Y.encodeStateAsUpdate(this.room.doc, Y.encodeStateVector(this.document)), this.room);\n if (this.authorizedScope === 'read-write') Y.applyUpdate(this.room.doc, Y.encodeStateAsUpdate(this.document, Y.encodeStateVector(this.room.doc)), this);\n for (const peer of this.peers()) {\n applyAwarenessUpdate(this.awareness, encodeAwarenessUpdate(peer.awareness, [peer.awareness.clientID]), this.room);\n applyAwarenessUpdate(peer.awareness, encodeAwarenessUpdate(this.awareness, [this.awareness.clientID]), this.room);\n }\n this.isSynced = true;\n } else for (const peer of this.peers()) removeAwarenessStates(peer.awareness, [this.awareness.clientID], this.room);\n this.emit('status', { status: on ? 'connected' : 'disconnected' });\n if (on) this.emit('synced', { state: true });\n }\n\n private local = (update: Uint8Array, origin: unknown) => {\n if (this.live && origin !== this.room && this.authorizedScope === 'read-write') Y.applyUpdate(this.room.doc, update, this);\n };\n\n private remote = (update: Uint8Array, origin: unknown) => {\n if (this.live && origin !== this) Y.applyUpdate(this.document, update, this.room);\n };\n\n private presence = ({ added, updated, removed }: { added: number[]; updated: number[]; removed: number[] }, origin: unknown) => {\n if (!this.live || origin === this.room) return;\n const update = encodeAwarenessUpdate(this.awareness, [...added, ...updated, ...removed]);\n for (const peer of this.peers()) applyAwarenessUpdate(peer.awareness, update, this.room);\n };\n\n private store() {\n const room = this.room;\n const run = room.busy.then(async () => {\n const done = await save(room.doc, this.kind, room.base ?? await this.host.content(this.id), async (bytes, note) => (await this.host.save!(this.id, bytes, note)).versionId);\n if (done) room.base = done.bytes;\n return done;\n });\n room.busy = run.catch(() => null);\n return run;\n }\n\n sendStateless(payload: string) {\n if (!this.live || this.authorizedScope !== 'read-write' || !(JSON.parse(payload) as { save?: boolean }).save) return;\n this.store().then(\n done => this.emit('stateless', { payload: JSON.stringify({ saved: done?.version ?? null }) }),\n () => this.emit('stateless', { payload: JSON.stringify({ failed: true }) }),\n );\n }\n\n destroy() {\n this.online(false);\n this.room.links.delete(this);\n this.stop();\n this.document.off('update', this.local);\n this.awareness.off('update', this.presence);\n this.room.doc.off('update', this.remote);\n this.awareness.destroy();\n if (!this.room.links.size && pending(this.room.doc) && this.authorizedScope === 'read-write') this.store().catch(() => null);\n }\n}\n"],"mappings":"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","names":["Y","host","wire","state","save"]}
@@ -0,0 +1,31 @@
1
+ 'use client';
2
+
3
+ // src/focus.ts
4
+ import { useLayoutEffect } from "react";
5
+ var pops = ".w100n-text-pop, .w100n-sheet-pop, .w100n-pdf-pop, .w100n-pdf-more";
6
+ function rove(e) {
7
+ const target = e.target;
8
+ if (!["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key) || e.altKey || e.metaKey || e.ctrlKey || target.closest('input, textarea, select, [contenteditable="true"]')) return;
9
+ const pop = target.closest(pops);
10
+ const list = [...(pop ?? e.currentTarget).querySelectorAll("button:not(:disabled)")].filter((el) => el.closest(pops) === pop);
11
+ const at = list.indexOf(target);
12
+ if (at < 0) return;
13
+ e.preventDefault();
14
+ e.stopPropagation();
15
+ list[e.key === "Home" ? 0 : e.key === "End" ? list.length - 1 : (at + (e.key === "ArrowRight" ? 1 : -1) + list.length) % list.length].focus();
16
+ }
17
+ function useRestore(open) {
18
+ useLayoutEffect(() => {
19
+ if (!open) return;
20
+ const back = document.activeElement instanceof HTMLElement ? document.activeElement : null;
21
+ return () => {
22
+ if (back?.isConnected) back.focus();
23
+ };
24
+ }, [open]);
25
+ }
26
+
27
+ export {
28
+ rove,
29
+ useRestore
30
+ };
31
+ //# sourceMappingURL=chunk-TDP6OJET.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/focus.ts"],"sourcesContent":["import { useLayoutEffect, type KeyboardEvent } from 'react';\n\nconst pops = '.w100n-text-pop, .w100n-sheet-pop, .w100n-pdf-pop, .w100n-pdf-more';\n\nexport function rove(e: KeyboardEvent<HTMLElement>) {\n const target = e.target as HTMLElement;\n if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key) || e.altKey || e.metaKey || e.ctrlKey || target.closest('input, textarea, select, [contenteditable=\"true\"]')) return;\n const pop = target.closest(pops);\n const list = [...(pop ?? e.currentTarget).querySelectorAll<HTMLElement>('button:not(:disabled)')].filter(el => el.closest(pops) === pop);\n const at = list.indexOf(target);\n if (at < 0) return;\n e.preventDefault();\n e.stopPropagation();\n list[e.key === 'Home' ? 0 : e.key === 'End' ? list.length - 1 : (at + (e.key === 'ArrowRight' ? 1 : -1) + list.length) % list.length].focus();\n}\n\nexport function useRestore(open: boolean) {\n useLayoutEffect(() => {\n if (!open) return;\n const back = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n return () => { if (back?.isConnected) back.focus(); };\n }, [open]);\n}\n"],"mappings":";;;AAAA,SAAS,uBAA2C;AAEpD,IAAM,OAAO;AAEN,SAAS,KAAK,GAA+B;AAClD,QAAM,SAAS,EAAE;AACjB,MAAI,CAAC,CAAC,aAAa,cAAc,QAAQ,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,OAAO,QAAQ,mDAAmD,EAAG;AAC9K,QAAM,MAAM,OAAO,QAAQ,IAAI;AAC/B,QAAM,OAAO,CAAC,IAAI,OAAO,EAAE,eAAe,iBAA8B,uBAAuB,CAAC,EAAE,OAAO,QAAM,GAAG,QAAQ,IAAI,MAAM,GAAG;AACvI,QAAM,KAAK,KAAK,QAAQ,MAAM;AAC9B,MAAI,KAAK,EAAG;AACZ,IAAE,eAAe;AACjB,IAAE,gBAAgB;AAClB,OAAK,EAAE,QAAQ,SAAS,IAAI,EAAE,QAAQ,QAAQ,KAAK,SAAS,KAAK,MAAM,EAAE,QAAQ,eAAe,IAAI,MAAM,KAAK,UAAU,KAAK,MAAM,EAAE,MAAM;AAC9I;AAEO,SAAS,WAAW,MAAe;AACxC,kBAAgB,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,SAAS,yBAAyB,cAAc,SAAS,gBAAgB;AACtF,WAAO,MAAM;AAAE,UAAI,MAAM,YAAa,MAAK,MAAM;AAAA,IAAG;AAAA,EACtD,GAAG,CAAC,IAAI,CAAC;AACX;","names":[]}