gutterpress 0.9.0-alpha.2 → 0.10.0-alpha.4

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 (138) hide show
  1. package/README.md +18 -4
  2. package/dist/api/index.d.ts +11 -5
  3. package/dist/api/index.js +20 -15
  4. package/dist/assets/preview/scripts/preview-bridge.d.ts +1 -0
  5. package/dist/assets/preview/scripts/preview-interface.d.ts +1 -0
  6. package/dist/{audit-nhn2pjz3.js → audit-k1vnfwvc.js} +10 -7
  7. package/dist/{build-san7fv2z.js → build-hqmwgvdw.js} +14 -8
  8. package/dist/checks/source/index.d.ts +1 -0
  9. package/dist/checks/source/layout-markers.d.ts +3 -0
  10. package/dist/checks/source/local-ref-parser.d.ts +28 -0
  11. package/dist/{cli-e5zhb0xs.js → cli-0r0tq16s.js} +17 -24
  12. package/dist/cli-46ycxe6r.js +18 -0
  13. package/dist/cli-c41yr7he.js +241 -0
  14. package/dist/cli-hp9r2pzt.js +2343 -0
  15. package/dist/{index-yzrh708h.js → cli-k1065rkg.js} +2 -5
  16. package/dist/{cli-k4bd06sd.js → cli-n25qycwz.js} +4986 -5889
  17. package/dist/{cli-najycadg.js → cli-ra0ed2xt.js} +69 -253
  18. package/dist/{cli-506tg37g.js → cli-revgt4pr.js} +2 -1
  19. package/dist/{cli-wchtvxvw.js → cli-v5mp7a6q.js} +14 -1
  20. package/dist/cli.js +20 -18
  21. package/dist/{doctor-hrk0kxxz.js → doctor-dxms7ehm.js} +4 -2
  22. package/dist/engine/compiler/build.d.ts +139 -0
  23. package/dist/engine/compiler/postprocess.d.ts +23 -0
  24. package/dist/engine/compiler/tier2.d.ts +78 -0
  25. package/dist/engine/shared/cdp.d.ts +104 -0
  26. package/dist/engine/shared/content-value.d.ts +64 -0
  27. package/dist/engine/shared/gcpm-extract.d.ts +119 -0
  28. package/dist/engine/shared/margin-box-support.d.ts +12 -0
  29. package/dist/engine/shared/pdf-inspect.d.ts +24 -0
  30. package/dist/engine/shared/synthesis.d.ts +155 -0
  31. package/dist/engine-wa7y9av9.js +41 -0
  32. package/dist/engine-z4p9sr4h.js +40 -0
  33. package/dist/gutterpress-agent-1ctgfz92.js +576 -0
  34. package/dist/gutterpress-viewer-cem7dmr5.js +2349 -0
  35. package/dist/{index-bynn850m.js → index-05y3dnxq.js} +3049 -4015
  36. package/dist/index-9tyq9kks.js +708 -0
  37. package/dist/{cli-yzrh708h.js → index-mdefp0y5.js} +1 -1
  38. package/dist/{index-wchtvxvw.js → index-v5mp7a6q.js} +14 -1
  39. package/dist/index-xxg4zfrg.js +1907 -0
  40. package/dist/index.d.ts +3 -1
  41. package/dist/index.js +24 -17
  42. package/dist/lib/asset-inline.d.ts +36 -0
  43. package/dist/lib/browser-pool.d.ts +18 -0
  44. package/dist/lib/build-error.d.ts +1 -1
  45. package/dist/lib/build-preflight.d.ts +35 -2
  46. package/dist/lib/build-runner.d.ts +45 -17
  47. package/dist/lib/build-staging.d.ts +9 -55
  48. package/dist/lib/cli-args.d.ts +8 -0
  49. package/dist/lib/desktop.d.ts +2 -2
  50. package/dist/lib/embedded-assets.d.ts +1 -1
  51. package/dist/lib/engine.d.ts +33 -0
  52. package/dist/lib/ghostscript.d.ts +46 -1
  53. package/dist/lib/markdown/assemble.d.ts +18 -10
  54. package/dist/lib/markdown/gp-pin-scope.d.ts +1 -0
  55. package/dist/lib/markdown/gutterpress-css.d.ts +125 -0
  56. package/dist/lib/markdown/images.d.ts +26 -0
  57. package/dist/lib/markdown/index.d.ts +4 -2
  58. package/dist/lib/markdown/inline-source.d.ts +10 -0
  59. package/dist/lib/markdown/markers.d.ts +32 -0
  60. package/dist/lib/markdown/renderer.d.ts +8 -3
  61. package/dist/lib/markdown/source-range.d.ts +61 -0
  62. package/dist/lib/missing-asset-placeholder.d.ts +52 -0
  63. package/dist/lib/presets.d.ts +1 -1
  64. package/dist/lib/printsafe.d.ts +2 -3
  65. package/dist/lib/remote-auth/converge-merge.d.ts +48 -0
  66. package/dist/lib/remote-auth/image-clash.d.ts +17 -0
  67. package/dist/lib/remote-auth/recovery/classify.d.ts +55 -67
  68. package/dist/lib/remote-auth/recovery/inspect.d.ts +14 -13
  69. package/dist/lib/remote-auth/recovery/locks.d.ts +20 -0
  70. package/dist/lib/remote-auth/recovery/repair.d.ts +29 -0
  71. package/dist/lib/remote-auth/recovery/types.d.ts +8 -204
  72. package/dist/lib/remote-auth/sync-messages.d.ts +2 -3
  73. package/dist/lib/remote-auth/sync-types.d.ts +35 -63
  74. package/dist/lib/remote-auth/sync.d.ts +11 -18
  75. package/dist/lib/remote-auth/transport.d.ts +14 -7
  76. package/dist/lib/theme-import.d.ts +4 -5
  77. package/dist/{lint-96j9hrj4.js → lint-xjwm5ep8.js} +10 -7
  78. package/dist/{manifest.schema-z61rzw44.json → manifest.schema-zxgxnbg7.json} +21 -0
  79. package/dist/{new-8p38wavc.js → new-kwdwpf0j.js} +12 -8
  80. package/dist/{plugin-ees6nhkc.js → plugin-rg4tnn96.js} +10 -7
  81. package/dist/{preflight-1q6c2edh.js → preflight-3127y25z.js} +10 -7
  82. package/dist/preview/file-watcher.d.ts +13 -17
  83. package/dist/preview/lifecycle.d.ts +1 -1
  84. package/dist/{pagedjs-bridge-vn4hk9fx.js → preview-bridge-fz7vpk8m.js} +8 -0
  85. package/dist/preview-interface-435cczt5.js +1059 -0
  86. package/dist/{preview-y5a2zen1.js → preview-ncgfhqmw.js} +16 -9
  87. package/dist/preview-shell-c5mfa3q0.js +346 -0
  88. package/dist/{project-source-p0gn1wd5.js → project-source-ekcyp63q.js} +1 -1
  89. package/dist/{publish-rm9yb3wh.js → publish-pr0rwh6p.js} +10 -7
  90. package/dist/render.d.ts +3 -4
  91. package/dist/render.js +728 -64
  92. package/dist/{repair-zgq7q2g6.js → repair-8270smfw.js} +45 -79
  93. package/dist/schema/manifest.types.d.ts +38 -0
  94. package/dist/{source-provider-c1rjm2c0.js → source-provider-3tcj6qg2.js} +2 -2
  95. package/dist/source-provider-vanafrt9.js +40 -0
  96. package/dist/{theme-zz2ktzqs.css → theme-h5recz6c.css} +8 -7
  97. package/dist/{theme-570zmh2t.css → theme-j2bagrfx.css} +8 -7
  98. package/dist/{theme-nya4nqh6.css → theme-nn6d53zy.css} +8 -7
  99. package/dist/types.d.ts +7 -0
  100. package/dist/{validate-nr0xa6sa.js → validate-54e17rae.js} +10 -7
  101. package/package.json +6 -6
  102. package/dist/cli-yja077f6.js +0 -92
  103. package/dist/git-http-yrb4ag6z.js +0 -17
  104. package/dist/index-yja077f6.js +0 -92
  105. package/dist/lib/markdown/markdown-it-paged.d.ts +0 -30
  106. package/dist/lib/pagedjs-marker.d.ts +0 -42
  107. package/dist/lib/pagedjs.d.ts +0 -26
  108. package/dist/lib/pagination.d.ts +0 -149
  109. package/dist/lib/remote-auth/conflict-resolution.d.ts +0 -29
  110. package/dist/lib/remote-auth/recovery/abort-interrupted-operation.d.ts +0 -103
  111. package/dist/lib/remote-auth/recovery/backup.d.ts +0 -113
  112. package/dist/lib/remote-auth/recovery/context.d.ts +0 -47
  113. package/dist/lib/remote-auth/recovery/dispatch.d.ts +0 -28
  114. package/dist/lib/remote-auth/recovery/failsafe.d.ts +0 -33
  115. package/dist/lib/remote-auth/recovery/manual-guidance.d.ts +0 -28
  116. package/dist/lib/remote-auth/recovery/outcome-mapping.d.ts +0 -59
  117. package/dist/lib/remote-auth/recovery/policy.d.ts +0 -47
  118. package/dist/lib/remote-auth/recovery/recover-auth.d.ts +0 -42
  119. package/dist/lib/remote-auth/recovery/recover-binary-conflict.d.ts +0 -37
  120. package/dist/lib/remote-auth/recovery/recover-corrupt-index.d.ts +0 -40
  121. package/dist/lib/remote-auth/recovery/recover-detached-head.d.ts +0 -70
  122. package/dist/lib/remote-auth/recovery/recover-interrupted-cherry-pick.d.ts +0 -23
  123. package/dist/lib/remote-auth/recovery/recover-interrupted-merge.d.ts +0 -28
  124. package/dist/lib/remote-auth/recovery/recover-interrupted-rebase.d.ts +0 -39
  125. package/dist/lib/remote-auth/recovery/recover-merge-conflict.d.ts +0 -34
  126. package/dist/lib/remote-auth/recovery/recover-missing-git-dir.d.ts +0 -37
  127. package/dist/lib/remote-auth/recovery/recover-missing-objects.d.ts +0 -56
  128. package/dist/lib/remote-auth/recovery/recover-network.d.ts +0 -34
  129. package/dist/lib/remote-auth/recovery/recover-non-fast-forward.d.ts +0 -27
  130. package/dist/lib/remote-auth/recovery/recover-stale-lock.d.ts +0 -68
  131. package/dist/lib/remote-auth/recovery/recover-unrelated-histories.d.ts +0 -44
  132. package/dist/lib/remote-auth/recovery/recover-wrong-remote.d.ts +0 -35
  133. package/dist/lib/remote-auth/resolution-plan.d.ts +0 -64
  134. package/dist/paged.polyfill-n95pbxfn.js +0 -33288
  135. package/dist/pagedjs-interface-qxvzgwd7.js +0 -557
  136. package/dist/preview-shell-6dqexx1m.js +0 -581
  137. /package/dist/assets/{preview/scripts/pagedjs-bridge.d.ts → engine/gutterpress-agent.d.ts} +0 -0
  138. /package/dist/assets/{preview/scripts/pagedjs-interface.d.ts → engine/gutterpress-viewer.d.ts} +0 -0
@@ -1,27 +1,31 @@
1
1
  import {
2
2
  previewArgs
3
- } from "./cli-506tg37g.js";
3
+ } from "./cli-revgt4pr.js";
4
4
  import {
5
5
  openPath,
6
6
  runBuild,
7
7
  splitOutPath,
8
8
  startPreviewServer
9
- } from "./cli-k4bd06sd.js";
9
+ } from "./cli-n25qycwz.js";
10
10
  import {
11
11
  log
12
- } from "./cli-najycadg.js";
12
+ } from "./cli-ra0ed2xt.js";
13
13
  import {
14
- BuildError,
15
14
  UsageError,
15
+ parseEngine,
16
16
  parseFormat,
17
17
  parsePdfxFlavor,
18
18
  rejectExtraPositionals,
19
19
  rejectUnknownFlags,
20
20
  resolvePort
21
- } from "./cli-e5zhb0xs.js";
22
- import"./cli-yzrh708h.js";
23
- import"./cli-wchtvxvw.js";
24
- import"./cli-yja077f6.js";
21
+ } from "./cli-0r0tq16s.js";
22
+ import"./cli-hp9r2pzt.js";
23
+ import"./cli-c41yr7he.js";
24
+ import {
25
+ BuildError
26
+ } from "./cli-46ycxe6r.js";
27
+ import"./cli-k1065rkg.js";
28
+ import"./cli-v5mp7a6q.js";
25
29
  import"./cli-37x76zdn.js";
26
30
 
27
31
  // src/commands/preview.ts
@@ -44,6 +48,7 @@ var preview_default = defineCommand({
44
48
  }
45
49
  }
46
50
  const openFlag = args.open;
51
+ const engine = parseEngine(args.engine);
47
52
  if (format === "html") {
48
53
  if (typeof args.manifest === "string") {
49
54
  throw new UsageError("--manifest is only supported by preview --format pdf or pdfx; live HTML preview discovers the project manifest from its input directory.");
@@ -55,7 +60,8 @@ var preview_default = defineCommand({
55
60
  noWatch: args.watch === false,
56
61
  verbose: !!args.verbose,
57
62
  openBrowser: openFlag,
58
- debug: !!args.debug
63
+ debug: !!args.debug,
64
+ engine
59
65
  });
60
66
  return;
61
67
  }
@@ -76,6 +82,7 @@ var preview_default = defineCommand({
76
82
  skipLint: !!args["skip-lint"],
77
83
  skipPreValidate: !!args["skip-pre-validate"],
78
84
  skipPostValidate: !!args["skip-post-validate"],
85
+ engine,
79
86
  rawArgs: args
80
87
  });
81
88
  if (openFlag && result.pdfPath) {
@@ -0,0 +1,346 @@
1
+ // Gutterpress preview shell controller (shared by the CLI preview and Electron).
2
+ // A Markdown edit paginates only that source file and replaces its live pages;
3
+ // geometry-wide changes paginate and atomically swap a fresh full document.
4
+ (function () {
5
+ 'use strict';
6
+ var active = document.getElementById('gutterpress-active');
7
+ var building = null;
8
+ var hotReloadFrame = null;
9
+ var retiring = null;
10
+ var initialInstance = window.__GUTTERPRESS_INSTANCE;
11
+ var initialRevision = Number(window.__GUTTERPRESS_REVISION);
12
+ var appliedInstance = typeof initialInstance === 'string' ? initialInstance : '';
13
+ var appliedRevision = Number.isSafeInteger(initialRevision) && initialRevision >= 0 ? initialRevision : 0;
14
+ var desiredInstance = appliedInstance;
15
+ var desiredRevision = appliedRevision;
16
+ var reportAppliedState = function () {};
17
+ var activeReady = false;
18
+ var lastViewportChangeAt = 0;
19
+ var pendingSwap = null;
20
+ var pendingSwapTimer = null;
21
+ var SCROLL_IDLE_MS = 250;
22
+ if (!active) return;
23
+
24
+ // Transparent bridge relay: forward host-toolbar commands to the active book
25
+ // iframe and relay its replies/events back to the host.
26
+ window.addEventListener('message', function (e) {
27
+ try {
28
+ if (window.parent !== window && e.source === window.parent) {
29
+ if (active && active.contentWindow) active.contentWindow.postMessage(e.data, '*');
30
+ } else if (active && e.source === active.contentWindow) {
31
+ var data = e.data;
32
+ if (data && data.type === 'gutterpress:event' && data.name === 'viewportChanged') {
33
+ lastViewportChangeAt = Date.now();
34
+ if (pendingSwap) armPendingSwap();
35
+ }
36
+ if (active === hotReloadFrame && data && data.type === 'gutterpress:event' && data.name === 'ready') return;
37
+ if (active === hotReloadFrame && data && data.type === 'gutterpress:event' && data.name === 'renderingComplete') {
38
+ var detail = {}, sourceDetail = data.detail || {};
39
+ for (var key in sourceDetail) {
40
+ if (Object.prototype.hasOwnProperty.call(sourceDetail, key)) detail[key] = sourceDetail[key];
41
+ }
42
+ detail.hotReload = true;
43
+ var startedAt = hotReloadFrame.__gutterpressReloadStartedAt;
44
+ detail.hotReloadMs = typeof startedAt === 'number' ? Math.max(0, Date.now() - startedAt) : 0;
45
+ detail.revision = hotReloadFrame.__gutterpressRevision;
46
+ detail.updateMode = 'full-reload';
47
+ data = { type: data.type, name: data.name, detail: detail };
48
+ hotReloadFrame = null;
49
+ }
50
+ if (window.parent !== window) window.parent.postMessage(data, '*');
51
+ } else if (retiring && e.source === retiring.contentWindow && window.parent !== window) {
52
+ var retiringData = e.data;
53
+ if (
54
+ retiringData &&
55
+ (retiringData.type === 'gutterpress:reply' ||
56
+ (retiringData.type === 'gutterpress:event' &&
57
+ retiringData.name === 'sourceLineChanged'))
58
+ ) window.parent.postMessage(retiringData, '*');
59
+ }
60
+ } catch (_) {}
61
+ });
62
+
63
+ function fdoc(f) { try { return f.contentDocument; } catch (_) { return null; } }
64
+ function fwin(f) { try { return f.contentWindow; } catch (_) { return null; } }
65
+ function capture(f) {
66
+ var w = fwin(f);
67
+ return w ? { x: w.scrollX, y: w.scrollY } : null;
68
+ }
69
+
70
+ function restore(f, anchor) {
71
+ if (!anchor) return;
72
+ var w = fwin(f);
73
+ if (w) w.scrollTo({ left: anchor.x, top: anchor.y, behavior: 'instant' });
74
+ }
75
+
76
+ // Carry desktop canvas/debug CSS and view state into the hidden replacement
77
+ // so its first visible paint matches the frame it replaces.
78
+ function copyPresentation(from, to) {
79
+ var source = fdoc(from), target = fdoc(to), targetWindow = fwin(to);
80
+ if (!source || !target || !targetWindow) return;
81
+ var styles = source.querySelectorAll(
82
+ 'style[data-gutterpress-desktop-canvas],style[data-gutterpress-debug]'
83
+ );
84
+ for (var i = 0; i < styles.length; i++) {
85
+ (target.head || target.documentElement).appendChild(styles[i].cloneNode(true));
86
+ }
87
+ var api = targetWindow.previewAPI;
88
+ var sourceBody = source.body;
89
+ if (api && sourceBody) {
90
+ if (sourceBody.classList.contains('view-single')) api.setViewMode('single', true);
91
+ else if (sourceBody.classList.contains('view-spread')) api.setViewMode('spread', true);
92
+ else if (sourceBody.classList.contains('view-two-column')) api.setViewMode('two-column', true);
93
+ if (sourceBody.classList.contains('debug')) api.toggleDebugMode();
94
+ }
95
+ var zoom = source.documentElement.style.getPropertyValue('--gutterpress-zoom');
96
+ if (api && zoom) api.setZoom(zoom, true);
97
+ }
98
+
99
+ function onReady(frame, callback, onTimeout, timeoutMs) {
100
+ var w = fwin(frame), d = fdoc(frame);
101
+ if (!w || !d) { callback(); return function () {}; }
102
+ var done = false, timer = null;
103
+ function cleanup() {
104
+ if (timer !== null) clearTimeout(timer);
105
+ w.removeEventListener('renderingComplete', finish);
106
+ }
107
+ function finish() {
108
+ if (done) return;
109
+ done = true;
110
+ cleanup();
111
+ callback();
112
+ }
113
+ // preview-interface.js's gp:layout listener re-dispatches
114
+ // 'renderingComplete' once the native viewer's pagination completes (see
115
+ // preview-interface.js's onRenderingComplete()).
116
+ w.addEventListener('renderingComplete', finish);
117
+ if (w.__GUTTERPRESS_RENDERED__ === true) {
118
+ setTimeout(finish, 0);
119
+ }
120
+ timer = setTimeout(function () {
121
+ if (done) return;
122
+ done = true;
123
+ cleanup();
124
+ if (onTimeout) onTimeout();
125
+ }, timeoutMs || 180000);
126
+ return function () { done = true; cleanup(); };
127
+ }
128
+
129
+ function discardBuilding() {
130
+ if (!building) return;
131
+ if (typeof building.__gutterpressCancelReady === 'function') {
132
+ building.__gutterpressCancelReady();
133
+ }
134
+ if (building.parentNode) building.parentNode.removeChild(building);
135
+ building = null;
136
+ }
137
+
138
+ function swap(instance, revision) {
139
+ discardBuilding();
140
+ var frame = document.createElement('iframe');
141
+ frame.style.visibility = 'hidden';
142
+ frame.setAttribute('aria-hidden', 'true');
143
+ frame.title = active.title || 'preview';
144
+ frame.__gutterpressReloadStartedAt = Date.now();
145
+ frame.__gutterpressInstance = instance;
146
+ frame.__gutterpressRevision = revision;
147
+ frame.src = '/book.html?gutterpressshell=1&instance=' + encodeURIComponent(instance)
148
+ + '&revision=' + revision + '&bust=' + Date.now();
149
+ building = frame;
150
+
151
+ var finished = false;
152
+ function finish() {
153
+ if (finished || building !== frame) return;
154
+ finished = true;
155
+ frame.__gutterpressCancelReady = null;
156
+ var activeApi = fwin(active) && fwin(active).previewAPI;
157
+ var pendingSource = activeApi && typeof activeApi.flushScroll === 'function'
158
+ ? activeApi.flushScroll(true)
159
+ : null;
160
+ if (pendingSource && window.parent !== window) {
161
+ window.parent.postMessage({
162
+ type: 'gutterpress:event',
163
+ name: 'sourceLineChanged',
164
+ detail: pendingSource
165
+ }, '*');
166
+ }
167
+ var anchor = capture(active);
168
+ copyPresentation(active, frame);
169
+ restore(frame, anchor);
170
+ var old = active;
171
+ old.removeAttribute('id');
172
+ frame.id = 'gutterpress-active';
173
+ retiring = old;
174
+ active = frame;
175
+ hotReloadFrame = frame;
176
+ building = null;
177
+ var api = fwin(frame) && fwin(frame).previewAPI;
178
+ if (api && typeof api.refresh === 'function') api.refresh();
179
+ frame.style.visibility = 'visible';
180
+ frame.removeAttribute('aria-hidden');
181
+ appliedInstance = instance;
182
+ appliedRevision = revision;
183
+ activeReady = true;
184
+ reportAppliedState(appliedInstance, appliedRevision);
185
+ requestAnimationFrame(function () {
186
+ requestAnimationFrame(function () {
187
+ if (old && old.parentNode) old.parentNode.removeChild(old);
188
+ if (retiring === old) retiring = null;
189
+ });
190
+ });
191
+ }
192
+
193
+ frame.addEventListener('load', function () {
194
+ frame.__gutterpressCancelReady = onReady(frame, finish, function () {
195
+ if (building !== frame) return;
196
+ if (window.parent !== window) {
197
+ window.parent.postMessage({
198
+ type: 'gutterpress:event',
199
+ name: 'renderingCancelled',
200
+ detail: { hotReload: true, revision: frame.__gutterpressRevision }
201
+ }, '*');
202
+ }
203
+ discardBuilding();
204
+ if (window.console) console.warn('[gutterpress] replacement pagination timed out');
205
+ });
206
+ });
207
+ document.body.appendChild(frame);
208
+ }
209
+
210
+ // Paginating a large replacement frame monopolizes Chromium's renderer
211
+ // thread. Starting it in the middle of a wheel gesture makes the visible
212
+ // preview appear to seize and then jump. Autosave has already decided WHEN
213
+ // content is ready; this tiny gate only waits when the reader is actively
214
+ // scrolling, then starts immediately after a short quiet period.
215
+ function beginPendingSwap() {
216
+ pendingSwapTimer = null;
217
+ var next = pendingSwap;
218
+ pendingSwap = null;
219
+ if (!next) return;
220
+ if (window.parent !== window) {
221
+ window.parent.postMessage({
222
+ type: 'gutterpress:event',
223
+ name: 'renderingStarted',
224
+ detail: { hotReload: true, revision: next.revision }
225
+ }, '*');
226
+ }
227
+ swap(next.instance, next.revision);
228
+ }
229
+
230
+ function armPendingSwap() {
231
+ if (pendingSwapTimer !== null) clearTimeout(pendingSwapTimer);
232
+ var delay = Math.max(0, SCROLL_IDLE_MS - (Date.now() - lastViewportChangeAt));
233
+ if (delay === 0) beginPendingSwap();
234
+ else pendingSwapTimer = setTimeout(beginPendingSwap, delay);
235
+ }
236
+
237
+ function scheduleSwap(instance, revision) {
238
+ pendingSwap = { instance: instance, revision: revision };
239
+ armPendingSwap();
240
+ }
241
+
242
+ // Incremental chapter splice used to live here (spliceChapter): it needed
243
+ // Paged.js's `.pagedjs_page` DOM to find a chapter's live page range and
244
+ // graft a freshly-paginated replacement into it. Paged.js has been removed
245
+ // (native-only-migration-plan.md Phase 6). A native in-place splice was
246
+ // also tried and removed (2026-08-08 review): grafting a fresh
247
+ // `.gutterpress-chapter` node in and calling `Gutterpress.refresh()` is not
248
+ // sound, because `refresh()` -> `relayout()` only re-`measure()`s the
249
+ // EXISTING strips — it never re-runs `buildStrips()`/`explodeChildren()`.
250
+ // So any page context the edit introduces (a new `@page`/`page:`
251
+ // assignment inside the chapter) is silently dropped: measured 2 preview
252
+ // pages where the same content prints 3 — a preview<->PDF divergence, the
253
+ // worst failure this project can produce. It also bought nothing: measured
254
+ // end-to-end (file write -> change visible, 5 samples, 34pp field guide)
255
+ // the plain full reload (`swap`, below) is 509ms avg vs the incremental
256
+ // splice's 998ms avg. Every content-update now goes straight to `swap()`.
257
+
258
+ function markActiveReady() {
259
+ onReady(active, function () {
260
+ activeReady = true;
261
+ reportAppliedState(appliedInstance, appliedRevision);
262
+ });
263
+ }
264
+ if (active.contentDocument && active.contentDocument.readyState === 'complete') markActiveReady();
265
+ active.addEventListener('load', markActiveReady);
266
+
267
+ function connectChanges(onMessage) {
268
+ var source = window.__GUTTERPRESS_CHANGE_SOURCE;
269
+ if (source && typeof source.subscribe === 'function') {
270
+ reportAppliedState = function (instance, revision) {
271
+ if (typeof source.acknowledge === 'function') source.acknowledge(instance, revision);
272
+ };
273
+ var unsubscribe = source.subscribe(onMessage);
274
+ return typeof unsubscribe === 'function' ? unsubscribe : function () {};
275
+ }
276
+ var wsPath = window.__GUTTERPRESS_HMR || '/__gutterpress-hmr';
277
+ var ws = null;
278
+ var reconnectTimer = null;
279
+ var reconnectDelay = 250;
280
+ var stopped = false;
281
+
282
+ reportAppliedState = function (instance, revision) {
283
+ if (!ws || ws.readyState !== 1) return;
284
+ try {
285
+ ws.send(JSON.stringify({ type: 'reload-applied', instance: instance, revision: revision }));
286
+ } catch (_) {}
287
+ };
288
+
289
+ function connect() {
290
+ if (stopped) return;
291
+ ws = new WebSocket(location.origin.replace(/^http/, 'ws') + wsPath);
292
+ ws.onopen = function () {
293
+ reconnectDelay = 250;
294
+ if (activeReady) reportAppliedState(appliedInstance, appliedRevision);
295
+ };
296
+ ws.onmessage = function (event) {
297
+ var message;
298
+ try { message = JSON.parse(event.data); } catch (_) { return; }
299
+ onMessage(message);
300
+ };
301
+ ws.onclose = function () {
302
+ ws = null;
303
+ if (stopped || reconnectTimer !== null) return;
304
+ reconnectTimer = setTimeout(function () {
305
+ reconnectTimer = null;
306
+ connect();
307
+ }, reconnectDelay);
308
+ reconnectDelay = Math.min(reconnectDelay * 2, 5000);
309
+ };
310
+ ws.onerror = function () { try { ws.close(); } catch (_) {} };
311
+ }
312
+
313
+ connect();
314
+ return function () {
315
+ stopped = true;
316
+ if (reconnectTimer !== null) clearTimeout(reconnectTimer);
317
+ try { if (ws) ws.close(); } catch (_) {}
318
+ };
319
+ }
320
+
321
+ var disconnectChanges = connectChanges(function (message) {
322
+ if (!message || (
323
+ message.type !== 'reload-state' &&
324
+ message.type !== 'full-reload' &&
325
+ message.type !== 'content-update'
326
+ )) return;
327
+ var instance = typeof message.instance === 'string' ? message.instance : null;
328
+ var revision = Number(message.revision);
329
+ if (!instance || !Number.isSafeInteger(revision) || revision < 0) return;
330
+ if (instance === appliedInstance && revision <= appliedRevision) {
331
+ if (activeReady) reportAppliedState(appliedInstance, appliedRevision);
332
+ return;
333
+ }
334
+ if (
335
+ instance === desiredInstance &&
336
+ (revision < desiredRevision || (revision === desiredRevision && (building || pendingSwap)))
337
+ ) return;
338
+ desiredInstance = instance;
339
+ desiredRevision = revision;
340
+ scheduleSwap(instance, revision);
341
+ });
342
+ window.addEventListener('beforeunload', function () {
343
+ if (pendingSwapTimer !== null) clearTimeout(pendingSwapTimer);
344
+ disconnectChanges();
345
+ });
346
+ })();
@@ -5,7 +5,7 @@ import {
5
5
  repoRootForSource,
6
6
  repoSubPath,
7
7
  syncRemoteFor
8
- } from "./cli-wchtvxvw.js";
8
+ } from "./cli-v5mp7a6q.js";
9
9
  import"./cli-37x76zdn.js";
10
10
  export {
11
11
  syncRemoteFor,
@@ -7,20 +7,23 @@ import {
7
7
  publishCredentialKey,
8
8
  publishProviderFor,
9
9
  runPublish
10
- } from "./cli-k4bd06sd.js";
10
+ } from "./cli-n25qycwz.js";
11
11
  import {
12
12
  FileTokenStore,
13
13
  log
14
- } from "./cli-najycadg.js";
14
+ } from "./cli-ra0ed2xt.js";
15
15
  import {
16
- EXIT_CODES,
17
16
  UsageError,
18
17
  rejectExtraPositionals,
19
18
  rejectUnknownFlags
20
- } from "./cli-e5zhb0xs.js";
21
- import"./cli-yzrh708h.js";
22
- import"./cli-wchtvxvw.js";
23
- import"./cli-yja077f6.js";
19
+ } from "./cli-0r0tq16s.js";
20
+ import"./cli-hp9r2pzt.js";
21
+ import"./cli-c41yr7he.js";
22
+ import {
23
+ EXIT_CODES
24
+ } from "./cli-46ycxe6r.js";
25
+ import"./cli-k1065rkg.js";
26
+ import"./cli-v5mp7a6q.js";
24
27
  import"./cli-37x76zdn.js";
25
28
 
26
29
  // src/commands/publish.ts
package/dist/render.d.ts CHANGED
@@ -3,8 +3,8 @@
3
3
  *
4
4
  * §1/§8 / ADR 0004: this entry deliberately exposes ONLY the browser-safe
5
5
  * markdown→HTML→book.html pieces. It transitively imports markdown-it + its
6
- * plugins, the inlined `markdown-it-paged.js`, and pure helpers — and NOTHING
7
- * from `node:*`/`fs`/`path`/`url`. This is what the desktop's WebAdapter imports
6
+ * plugins, Gutterpress's inlined marker parser (`markers.js`), and pure helpers
7
+ * — and NOTHING from `node:*`/`fs`/`path`/`url`. This is what the desktop's WebAdapter imports
8
8
  * (a *value* import that stays PWA-clean), so the in-browser live preview (#33)
9
9
  * can render the opened project entirely client-side with no localhost server
10
10
  * and no puppeteer.
@@ -16,5 +16,4 @@ export { assembleBookHtml } from "./lib/markdown/assemble";
16
16
  export type { AssembleBookHtmlOptions, ReadText, } from "./lib/markdown/assemble";
17
17
  export { createMarkdownRenderer, collectPluginCss, applyPlugins } from "./lib/markdown/renderer";
18
18
  export type { LoadedPlugin, GutterpressPlugin, GutterpressPluginMetadata, GutterpressPluginExport, } from "./lib/markdown/renderer";
19
- export { PAGED_CSS } from "./lib/markdown/markdown-it-paged.js";
20
- export { PAGEDJS_VERSION, PAGEDJS_POLYFILL_MARKER, pagedjsPolyfillTag, pagedjsPolyfillTagRegex, } from "./lib/pagedjs-marker";
19
+ export { MARKER_CSS } from "./lib/markdown/markers.js";