@1agh/maude 1.3.0 → 1.3.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/apps/studio/api.ts +43 -2
- package/apps/studio/canvas-build.ts +49 -8
- package/apps/studio/canvas-edit.ts +77 -0
- package/apps/studio/canvas-list-watch.ts +33 -2
- package/apps/studio/client/app.jsx +97 -4
- package/apps/studio/client/canvas-url.js +39 -1
- package/apps/studio/client/styles/3-shell-maude.css +1 -0
- package/apps/studio/collab/awareness-bridge.ts +65 -14
- package/apps/studio/dist/client.bundle.js +449 -449
- package/apps/studio/dist/comment-mount.js +2 -2
- package/apps/studio/dist/styles.css +1 -1
- package/apps/studio/git/accepted-guard.ts +36 -0
- package/apps/studio/hmr-broadcast.ts +34 -1
- package/apps/studio/http.ts +11 -0
- package/apps/studio/managed-projects.ts +22 -0
- package/apps/studio/sync/index.ts +106 -12
- package/apps/studio/sync/presentation.ts +30 -0
- package/apps/studio/sync/status.ts +5 -1
- package/apps/studio/sync/transaction-client.ts +26 -0
- package/apps/studio/use-tool-mode.tsx +44 -0
- package/apps/studio/whats-new.json +36 -0
- package/package.json +8 -8
- package/plugins/design/templates/_shell.html +48 -7
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
// module, its tokens, its components CSS and its meta as separate
|
|
206
206
|
// requests. Getting the document through and nothing else is what
|
|
207
207
|
// "refused to connect" looks like from the outside.
|
|
208
|
-
|
|
208
|
+
let cap = params.get('t') || '';
|
|
209
209
|
// THE BASE THIS DOCUMENT WAS SERVED FROM, not the origin root.
|
|
210
210
|
//
|
|
211
211
|
// The fleet's canvas origin puts the project in the PATH
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
return cap ? abs + (abs.includes('?') ? '&' : '?') + 't=' + encodeURIComponent(cap) : abs;
|
|
224
224
|
};
|
|
225
225
|
const canvasQuery = shaParam ? ('?sha=' + encodeURIComponent(shaParam)) : '';
|
|
226
|
-
|
|
226
|
+
let canvasUrl = canvasRel ? withCap('/' + designRel + '/' + canvasRel + canvasQuery) : null;
|
|
227
227
|
const myFileKey = canvasRel ? (designRel + '/' + canvasRel) : null;
|
|
228
228
|
// True while an `ai-activity` entry is live for THIS canvas (an agent is
|
|
229
229
|
// running /design:edit|new on it). Mirrors ai-banner's gate: parent relays
|
|
@@ -250,6 +250,19 @@
|
|
|
250
250
|
// The panel just optimistically applied an edit → skip the redundant
|
|
251
251
|
// follow-up module reload (set here, parent-verified).
|
|
252
252
|
lastCssOptimisticAt = Date.now();
|
|
253
|
+
} else if (m.dgn === 'canvas-cap') {
|
|
254
|
+
// A re-minted capability (it expires; app.jsx refreshes it). Every
|
|
255
|
+
// URL built from here on carries it, and asking for this shell
|
|
256
|
+
// document with it re-plants the origin's cookie — the one module
|
|
257
|
+
// imports, assets and the live sockets fall back to. Without this an
|
|
258
|
+
// open canvas stopped loading and updating once its first capability
|
|
259
|
+
// expired. Only a well-formed token, and only in the cloud (a
|
|
260
|
+
// desktop canvas never had one).
|
|
261
|
+
const t = m.t;
|
|
262
|
+
if (!cap || typeof t !== 'string' || t.length > 4096 || !/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(t)) return;
|
|
263
|
+
cap = t;
|
|
264
|
+
if (canvasRel) canvasUrl = withCap('/' + designRel + '/' + canvasRel + canvasQuery);
|
|
265
|
+
fetch(withCap('/_canvas-shell.html'), { cache: 'no-store', credentials: 'same-origin' }).catch(() => {});
|
|
253
266
|
}
|
|
254
267
|
});
|
|
255
268
|
|
|
@@ -394,12 +407,22 @@
|
|
|
394
407
|
if (msg.type !== 'canvas-hmr') return;
|
|
395
408
|
if (msg.mode === 'css') {
|
|
396
409
|
const v = msg.version || Date.now();
|
|
397
|
-
// Match by
|
|
398
|
-
|
|
410
|
+
// Match by PATH when we have one; otherwise refresh all. By path,
|
|
411
|
+
// not by file name: every design system has a `tokens.css`, and
|
|
412
|
+
// a change to one canvas's imported `system/<a>/tokens.css`
|
|
413
|
+
// "matched" the shell's link to `system/<b>/tokens.css` — which
|
|
414
|
+
// swapped the wrong sheet and skipped the reload below that the
|
|
415
|
+
// changed one needed (plan T31/L16).
|
|
416
|
+
const changed = msg.file ? '/' + msg.file : '';
|
|
399
417
|
let matched = false;
|
|
400
418
|
for (const link of document.querySelectorAll('link[rel="stylesheet"]')) {
|
|
401
419
|
const href = link.getAttribute('href') || '';
|
|
402
|
-
if (!
|
|
420
|
+
if (!href) continue;
|
|
421
|
+
let linkPath = '';
|
|
422
|
+
try {
|
|
423
|
+
linkPath = decodeURIComponent(new URL(href, location.href).pathname);
|
|
424
|
+
} catch {}
|
|
425
|
+
if (!changed || linkPath.endsWith(changed)) {
|
|
403
426
|
const base = href.split('?')[0];
|
|
404
427
|
link.setAttribute('href', base + '?v=' + v);
|
|
405
428
|
matched = true;
|
|
@@ -416,7 +439,21 @@
|
|
|
416
439
|
if (!matched && msg.file && canvasRel) {
|
|
417
440
|
const cssDir = msg.file.replace(/[^/]+$/, '');
|
|
418
441
|
const canvasDir = canvasRel.replace(/[^/]+$/, '');
|
|
419
|
-
if (cssDir === canvasDir)
|
|
442
|
+
if (cssDir === canvasDir) {
|
|
443
|
+
location.reload();
|
|
444
|
+
} else {
|
|
445
|
+
// …and a stylesheet imported from ANYWHERE else (a design
|
|
446
|
+
// system's tokens.css) is inlined the same way. The module's
|
|
447
|
+
// style tag names what it inlined; re-import so it re-injects.
|
|
448
|
+
// (Canvas script could add names here, but that can only
|
|
449
|
+
// FORCE a reload — the safe direction.)
|
|
450
|
+
var bundled = document.querySelector('style[data-canvas-css="bundled"]');
|
|
451
|
+
var names = bundled && bundled.dataset.canvasCssSources ? bundled.dataset.canvasCssSources.split('|') : [];
|
|
452
|
+
if (names.indexOf(msg.file) !== -1) {
|
|
453
|
+
if (window.__maudeCanvasRuntime && window.__maudeCanvasRuntime.remount) softReload(v);
|
|
454
|
+
else location.reload();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
420
457
|
}
|
|
421
458
|
} else if (msg.mode === 'module' || msg.mode === 'hard') {
|
|
422
459
|
// Only reload when the change touches *this* canvas (or `_lib`).
|
|
@@ -443,7 +480,11 @@
|
|
|
443
480
|
// direction; it can never suppress one.)
|
|
444
481
|
var hasComps = false;
|
|
445
482
|
try { hasComps = !!(window.__maude_comps__ && window.__maude_comps__().length); } catch (err) { hasComps = false; }
|
|
446
|
-
|
|
483
|
+
// …but NEVER a sync write (`remote`): it can carry a
|
|
484
|
+
// teammate's change merged under this person's own edit (a
|
|
485
|
+
// lost race re-applied onto theirs), and skipping it left
|
|
486
|
+
// their change off this canvas until a manual reload.
|
|
487
|
+
if (!hasComps && !msg.remote && Date.now() - lastCssOptimisticAt < 1500) return;
|
|
447
488
|
}
|
|
448
489
|
// Phase 30 (F4) — prefer an in-place hot-swap for ANY canvas-body
|
|
449
490
|
// (`module`) change whenever the canvas runtime is mounted: the
|