Z User commited on
Commit
10c5bcc
·
1 Parent(s): 54a7dba

sync work in progress

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +0 -0
  2. bun.lock +0 -0
  3. components.json +0 -0
  4. eslint.config.mjs +0 -0
  5. examples/websocket/frontend.tsx +0 -0
  6. examples/websocket/server.ts +0 -0
  7. next.config.ts +0 -0
  8. package.json +0 -0
  9. postcss.config.mjs +0 -0
  10. prisma/schema.prisma +0 -0
  11. public/dssl/boot.js +0 -0
  12. public/dssl/engine.js +0 -0
  13. public/dssl/index.js +0 -0
  14. public/dssl/parser.js +0 -0
  15. public/dssl/resolver.js +0 -0
  16. public/dssl/utils.js +0 -0
  17. public/favicon.svg +0 -0
  18. public/logo.svg +0 -0
  19. public/robots.txt +0 -0
  20. public/styles/changelog.dssl +0 -0
  21. public/styles/docs.dssl +0 -0
  22. public/styles/home.dssl +0 -0
  23. public/styles/playground.dssl +0 -0
  24. public/styles/site.dssl +0 -0
  25. public/styles/tokens.dssl +0 -0
  26. scripts/dssl-debug-grid.mjs +0 -0
  27. scripts/dssl-smoke.mjs +0 -0
  28. scripts/dssl-styles-check.mjs +0 -0
  29. src/app/api/route.ts +0 -0
  30. src/app/globals.css +0 -0
  31. src/app/layout.tsx +30 -11
  32. src/app/page.tsx +0 -0
  33. src/components/dssl/CodeBlock.tsx +0 -0
  34. src/components/dssl/SiteRoot.tsx +0 -0
  35. src/components/dssl/highlight.ts +0 -0
  36. src/components/dssl/icons.tsx +0 -0
  37. src/components/dssl/views/ChangelogView.tsx +0 -0
  38. src/components/dssl/views/CheatSheetView.tsx +0 -0
  39. src/components/dssl/views/DocsView.tsx +58 -0
  40. src/components/dssl/views/HomeView.tsx +0 -0
  41. src/components/dssl/views/PlaygroundView.tsx +0 -0
  42. src/components/dssl/views/SpecView.tsx +0 -0
  43. src/components/ui/accordion.tsx +0 -0
  44. src/components/ui/alert-dialog.tsx +0 -0
  45. src/components/ui/alert.tsx +0 -0
  46. src/components/ui/aspect-ratio.tsx +0 -0
  47. src/components/ui/avatar.tsx +0 -0
  48. src/components/ui/badge.tsx +0 -0
  49. src/components/ui/breadcrumb.tsx +0 -0
  50. src/components/ui/button.tsx +0 -0
.gitignore CHANGED
File without changes
bun.lock CHANGED
File without changes
components.json CHANGED
File without changes
eslint.config.mjs CHANGED
File without changes
examples/websocket/frontend.tsx CHANGED
File without changes
examples/websocket/server.ts CHANGED
File without changes
next.config.ts CHANGED
File without changes
package.json CHANGED
File without changes
postcss.config.mjs CHANGED
File without changes
prisma/schema.prisma CHANGED
File without changes
public/dssl/boot.js CHANGED
File without changes
public/dssl/engine.js CHANGED
File without changes
public/dssl/index.js CHANGED
File without changes
public/dssl/parser.js CHANGED
File without changes
public/dssl/resolver.js CHANGED
File without changes
public/dssl/utils.js CHANGED
File without changes
public/favicon.svg CHANGED
public/logo.svg CHANGED
public/robots.txt CHANGED
File without changes
public/styles/changelog.dssl CHANGED
File without changes
public/styles/docs.dssl CHANGED
File without changes
public/styles/home.dssl CHANGED
File without changes
public/styles/playground.dssl CHANGED
File without changes
public/styles/site.dssl CHANGED
File without changes
public/styles/tokens.dssl CHANGED
File without changes
scripts/dssl-debug-grid.mjs CHANGED
File without changes
scripts/dssl-smoke.mjs CHANGED
File without changes
scripts/dssl-styles-check.mjs CHANGED
File without changes
src/app/api/route.ts CHANGED
File without changes
src/app/globals.css CHANGED
File without changes
src/app/layout.tsx CHANGED
@@ -46,27 +46,46 @@ function dsslInlineStyles(): { name: string; src: string }[] {
46
 
47
  // Dev-only interop shim: the engine styles the SSR DOM BEFORE React hydrates
48
  // (that is the whole point — no FOUC). React 19 then logs one console.error
49
- // about extra style attributes and, helpfully, does not patch them. On our own
50
- // site that reads as "1 Issue" in the dev overlay. This shim filters ONLY the
51
- // hydration notices whose diff references DSSL's var(--dssl-*) attributes and
52
- // re-tells them as an explained info line; any genuine mismatch still shows.
 
 
 
 
53
  const hydrationShim = `
54
  (function () {
55
- var HYD = 'A tree hydrated but some attributes of the server rendered HTML';
56
- var orig = console.error;
57
- console.error = function () {
 
 
58
  var s = '';
59
  for (var i = 0; i < arguments.length; i++) {
60
  var a = arguments[i];
61
- s += (typeof a === 'string' ? a : ' ');
62
  }
63
- if (s.indexOf(HYD) === 0 && s.indexOf('--dssl') !== -1) {
64
  console.info('%cDSSL%c styled this page before React hydrated. The "hydrated but some attributes didn\\u2019t match" notice is expected interop: the engine owns those style attributes, and React explicitly leaves them alone.',
65
  'background:#b3372e;color:#fff;padding:1px 6px;border-radius:3px;font-weight:700', '');
66
  return;
67
  }
68
- return orig.apply(console, arguments);
69
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  })();
71
  `;
72
 
 
46
 
47
  // Dev-only interop shim: the engine styles the SSR DOM BEFORE React hydrates
48
  // (that is the whole point — no FOUC). React 19 then logs one console.error
49
+ // about extra style attributes and, helpfully, does not patch them. Next's
50
+ // dev overlay ALSO patches console.error (one layer around everything) and
51
+ // counts every error it sees into the "Issues" badge — so a plain filter
52
+ // installed here would sit INSIDE Next's collector and the badge would still
53
+ // show "1". This shim instead installs an assignment trap: the moment Next
54
+ // assigns its own wrapper, we capture it and re-publish OUR filter as the
55
+ // outermost layer. DSSL's own hydration diff is swallowed + explained; every
56
+ // other console.error still reaches Next's collector untouched.
57
  const hydrationShim = `
58
  (function () {
59
+ var HYD = 'A tree hydrated but some attributes';
60
+ var MARK = '--dssl';
61
+ var inner = console.error; // native, until Next assigns its wrapper
62
+ var trapped = false;
63
+ function outer() {
64
  var s = '';
65
  for (var i = 0; i < arguments.length; i++) {
66
  var a = arguments[i];
67
+ s += (i ? ' ' : '') + (typeof a === 'string' ? a : (a && a.message ? a.message : ''));
68
  }
69
+ if (s.indexOf(HYD) !== -1 && s.indexOf(MARK) !== -1) {
70
  console.info('%cDSSL%c styled this page before React hydrated. The "hydrated but some attributes didn\\u2019t match" notice is expected interop: the engine owns those style attributes, and React explicitly leaves them alone.',
71
  'background:#b3372e;color:#fff;padding:1px 6px;border-radius:3px;font-weight:700', '');
72
  return;
73
  }
74
+ return inner.apply(console, arguments);
75
+ }
76
+ try {
77
+ var desc = Object.getOwnPropertyDescriptor(console, 'error');
78
+ if (!desc || !desc.configurable) throw new Error('not configurable');
79
+ Object.defineProperty(console, 'error', {
80
+ configurable: true,
81
+ get: function () { return trapped ? outer : inner; },
82
+ set: function (fn) { inner = fn; trapped = true; }
83
+ });
84
+ } catch (e) {
85
+ // fallback: plain filter — console noise is still explained away,
86
+ // though the dev-overlay badge may still count the notice.
87
+ console.error = outer;
88
+ }
89
  })();
90
  `;
91
 
src/app/page.tsx CHANGED
File without changes
src/components/dssl/CodeBlock.tsx CHANGED
File without changes
src/components/dssl/SiteRoot.tsx CHANGED
File without changes
src/components/dssl/highlight.ts CHANGED
File without changes
src/components/dssl/icons.tsx CHANGED
File without changes
src/components/dssl/views/ChangelogView.tsx CHANGED
File without changes
src/components/dssl/views/CheatSheetView.tsx CHANGED
File without changes
src/components/dssl/views/DocsView.tsx CHANGED
@@ -17,6 +17,7 @@ const SIDE = [
17
  { head: null, id: "motion", label: "Motion" },
18
  { head: null, id: "errors", label: "Errors" },
19
  { head: null, id: "api", label: "JS API" },
 
20
  ];
21
 
22
  export default function DocsView() {
@@ -443,6 +444,63 @@ button { use focus-ring }
443
  <code>&lt;html data-dssl-reset&gt;</code> enables the small built-in reset.
444
  </p>
445
  </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
446
  </div>
447
  </div>
448
  </div>
 
17
  { head: null, id: "motion", label: "Motion" },
18
  { head: null, id: "errors", label: "Errors" },
19
  { head: null, id: "api", label: "JS API" },
20
+ { head: null, id: "interop", label: "Interop (React & co.)" },
21
  ];
22
 
23
  export default function DocsView() {
 
444
  <code>&lt;html data-dssl-reset&gt;</code> enables the small built-in reset.
445
  </p>
446
  </section>
447
+
448
+ <section className="doc-block" id="interop">
449
+ <h2 className="section-title">Interop — React, hydration &amp; friends</h2>
450
+ <p className="doc-lead">
451
+ DSSL is deliberately framework-agnostic: it styles whatever DOM exists,
452
+ so it works under React, Vue, Svelte or plain HTML. But if you render
453
+ with React there is <b>one known, harmless notice</b> you should
454
+ understand — and this very site is the living example.
455
+ </p>
456
+ <div className="note">
457
+ <b>Why the notice happens.</b> The engine applies styles to the SSR DOM
458
+ <i> before</i> React hydrates — that is the whole anti-flash design. React
459
+ then compares the DOM against its virtual render, finds extra
460
+ <code> style="--dssl-*…"</code> attributes it did not put there, and logs
461
+ one hydration diff to the console. React explicitly <b>does not patch
462
+ them away</b> — it leaves the engine&apos;s styles alone. Nothing is wrong:
463
+ the styles are working exactly as intended.
464
+ </div>
465
+ <p className="doc-lead">
466
+ In dev builds that single notice can surface as a "1 Issue" overlay badge,
467
+ because Next&apos;s dev tools wrap <code>console.error</code> and count
468
+ everything they see. This site installs an <i>assignment trap</i>: the moment
469
+ Next assigns its own collector, the shim captures it and re-publishes the
470
+ filter as the <b>outermost</b> layer — so DSSL&apos;s own diff is swallowed
471
+ and re-logged as an explained info line <b>before</b> Next can count it.
472
+ Any genuine hydration mismatch still flows through to the collector at full
473
+ volume. In production React does not diff attributes at all, so the notice
474
+ disappears entirely; the shim is dev-only.
475
+ </p>
476
+ <CodeBlock file="dev-only console shim (this site's layout.tsx)" code={`// assignment trap: become the OUTERMOST console.error
477
+ // the moment Next assigns its own collector
478
+ let inner = console.error, trapped = false;
479
+ Object.defineProperty(console, 'error', {
480
+ configurable: true,
481
+ get: () => (trapped ? outer : inner),
482
+ set: (fn) => { inner = fn; trapped = true; }
483
+ });
484
+ function outer(...args) {
485
+ const s = args.map(String).join(' ');
486
+ // swallow ONLY the DSSL-attribute hydration diff
487
+ if (s.includes('A tree hydrated but some attributes')
488
+ && s.includes('--dssl')) {
489
+ console.info('DSSL styled this page before React hydrated. Expected interop.');
490
+ return;
491
+ }
492
+ return inner.apply(console, args); // genuine issues flow through
493
+ }`} />
494
+ <p className="doc-lead">
495
+ Two more interop notes worth knowing. First, if a framework re-renders a
496
+ subtree and <i>removes</i> elements the engine had styled, the touched
497
+ registry notices the removal via MutationObserver and cleans up — no
498
+ leaked inline styles. Second, if your framework toggles attributes the
499
+ engine matches on (like <code>data-dssl-*</code> signal mirrors), change
500
+ them through <code>DSSL.signal()</code> rather than DOM writes, so rules
501
+ re-evaluate on the same tick instead of waiting for the observer.
502
+ </p>
503
+ </section>
504
  </div>
505
  </div>
506
  </div>
src/components/dssl/views/HomeView.tsx CHANGED
File without changes
src/components/dssl/views/PlaygroundView.tsx CHANGED
File without changes
src/components/dssl/views/SpecView.tsx CHANGED
File without changes
src/components/ui/accordion.tsx CHANGED
File without changes
src/components/ui/alert-dialog.tsx CHANGED
File without changes
src/components/ui/alert.tsx CHANGED
File without changes
src/components/ui/aspect-ratio.tsx CHANGED
File without changes
src/components/ui/avatar.tsx CHANGED
File without changes
src/components/ui/badge.tsx CHANGED
File without changes
src/components/ui/breadcrumb.tsx CHANGED
File without changes
src/components/ui/button.tsx CHANGED
File without changes