mates-fullstack 1.0.0-beta.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.
Files changed (202) hide show
  1. package/README.md +311 -0
  2. package/dist/arctic-auth.d.ts +101 -0
  3. package/dist/arctic-auth.d.ts.map +1 -0
  4. package/dist/arctic-auth.js +538 -0
  5. package/dist/arctic-auth.js.map +1 -0
  6. package/dist/asset-manifest.d.ts +14 -0
  7. package/dist/asset-manifest.d.ts.map +1 -0
  8. package/dist/asset-manifest.js +102 -0
  9. package/dist/asset-manifest.js.map +1 -0
  10. package/dist/browser.d.ts +18 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +25 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/build-esbuild.d.ts +29 -0
  15. package/dist/build-esbuild.d.ts.map +1 -0
  16. package/dist/build-esbuild.js +699 -0
  17. package/dist/build-esbuild.js.map +1 -0
  18. package/dist/build-prod.d.ts +126 -0
  19. package/dist/build-prod.d.ts.map +1 -0
  20. package/dist/build-prod.js +1014 -0
  21. package/dist/build-prod.js.map +1 -0
  22. package/dist/cli-new.d.ts +14 -0
  23. package/dist/cli-new.d.ts.map +1 -0
  24. package/dist/cli-new.js +637 -0
  25. package/dist/cli-new.js.map +1 -0
  26. package/dist/client.d.ts +43 -0
  27. package/dist/client.d.ts.map +1 -0
  28. package/dist/client.js +130 -0
  29. package/dist/client.js.map +1 -0
  30. package/dist/cors.d.ts +16 -0
  31. package/dist/cors.d.ts.map +1 -0
  32. package/dist/cors.js +60 -0
  33. package/dist/cors.js.map +1 -0
  34. package/dist/ctx.d.ts +78 -0
  35. package/dist/ctx.d.ts.map +1 -0
  36. package/dist/ctx.js +280 -0
  37. package/dist/ctx.js.map +1 -0
  38. package/dist/dev-watcher.d.ts +23 -0
  39. package/dist/dev-watcher.d.ts.map +1 -0
  40. package/dist/dev-watcher.js +136 -0
  41. package/dist/dev-watcher.js.map +1 -0
  42. package/dist/docs-generator.d.ts +69 -0
  43. package/dist/docs-generator.d.ts.map +1 -0
  44. package/dist/docs-generator.js +557 -0
  45. package/dist/docs-generator.js.map +1 -0
  46. package/dist/docs-page.d.ts +20 -0
  47. package/dist/docs-page.d.ts.map +1 -0
  48. package/dist/docs-page.js +1152 -0
  49. package/dist/docs-page.js.map +1 -0
  50. package/dist/download.d.ts +78 -0
  51. package/dist/download.d.ts.map +1 -0
  52. package/dist/download.js +202 -0
  53. package/dist/download.js.map +1 -0
  54. package/dist/env-loader.d.ts +76 -0
  55. package/dist/env-loader.d.ts.map +1 -0
  56. package/dist/env-loader.js +213 -0
  57. package/dist/env-loader.js.map +1 -0
  58. package/dist/errors.d.ts +146 -0
  59. package/dist/errors.d.ts.map +1 -0
  60. package/dist/errors.js +386 -0
  61. package/dist/errors.js.map +1 -0
  62. package/dist/head.d.ts +31 -0
  63. package/dist/head.d.ts.map +1 -0
  64. package/dist/head.js +245 -0
  65. package/dist/head.js.map +1 -0
  66. package/dist/index.d.ts +30 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +30 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/internal-prefixes.d.ts +16 -0
  71. package/dist/internal-prefixes.d.ts.map +1 -0
  72. package/dist/internal-prefixes.js +16 -0
  73. package/dist/internal-prefixes.js.map +1 -0
  74. package/dist/internal.d.ts +25 -0
  75. package/dist/internal.d.ts.map +1 -0
  76. package/dist/internal.js +25 -0
  77. package/dist/internal.js.map +1 -0
  78. package/dist/jwt.d.ts +166 -0
  79. package/dist/jwt.d.ts.map +1 -0
  80. package/dist/jwt.js +261 -0
  81. package/dist/jwt.js.map +1 -0
  82. package/dist/log.d.ts +44 -0
  83. package/dist/log.d.ts.map +1 -0
  84. package/dist/log.js +66 -0
  85. package/dist/log.js.map +1 -0
  86. package/dist/logger.d.ts +76 -0
  87. package/dist/logger.d.ts.map +1 -0
  88. package/dist/logger.js +138 -0
  89. package/dist/logger.js.map +1 -0
  90. package/dist/main-runner.d.ts +59 -0
  91. package/dist/main-runner.d.ts.map +1 -0
  92. package/dist/main-runner.js +157 -0
  93. package/dist/main-runner.js.map +1 -0
  94. package/dist/mates-auth.d.ts +82 -0
  95. package/dist/mates-auth.d.ts.map +1 -0
  96. package/dist/mates-auth.js +323 -0
  97. package/dist/mates-auth.js.map +1 -0
  98. package/dist/middleware.d.ts +30 -0
  99. package/dist/middleware.d.ts.map +1 -0
  100. package/dist/middleware.js +67 -0
  101. package/dist/middleware.js.map +1 -0
  102. package/dist/project-resolver.d.ts +102 -0
  103. package/dist/project-resolver.d.ts.map +1 -0
  104. package/dist/project-resolver.js +271 -0
  105. package/dist/project-resolver.js.map +1 -0
  106. package/dist/rate-limit.d.ts +37 -0
  107. package/dist/rate-limit.d.ts.map +1 -0
  108. package/dist/rate-limit.js +109 -0
  109. package/dist/rate-limit.js.map +1 -0
  110. package/dist/redirect.d.ts +84 -0
  111. package/dist/redirect.d.ts.map +1 -0
  112. package/dist/redirect.js +105 -0
  113. package/dist/redirect.js.map +1 -0
  114. package/dist/renderer.d.ts +91 -0
  115. package/dist/renderer.d.ts.map +1 -0
  116. package/dist/renderer.js +630 -0
  117. package/dist/renderer.js.map +1 -0
  118. package/dist/request-logger.d.ts +12 -0
  119. package/dist/request-logger.d.ts.map +1 -0
  120. package/dist/request-logger.js +55 -0
  121. package/dist/request-logger.js.map +1 -0
  122. package/dist/rest.d.ts +25 -0
  123. package/dist/rest.d.ts.map +1 -0
  124. package/dist/rest.js +93 -0
  125. package/dist/rest.js.map +1 -0
  126. package/dist/router.d.ts +71 -0
  127. package/dist/router.d.ts.map +1 -0
  128. package/dist/router.js +222 -0
  129. package/dist/router.js.map +1 -0
  130. package/dist/rpc-registry.d.ts +84 -0
  131. package/dist/rpc-registry.d.ts.map +1 -0
  132. package/dist/rpc-registry.js +271 -0
  133. package/dist/rpc-registry.js.map +1 -0
  134. package/dist/rpc-runner.d.ts +82 -0
  135. package/dist/rpc-runner.d.ts.map +1 -0
  136. package/dist/rpc-runner.js +564 -0
  137. package/dist/rpc-runner.js.map +1 -0
  138. package/dist/sanitize.d.ts +61 -0
  139. package/dist/sanitize.d.ts.map +1 -0
  140. package/dist/sanitize.js +193 -0
  141. package/dist/sanitize.js.map +1 -0
  142. package/dist/security-headers.d.ts +114 -0
  143. package/dist/security-headers.d.ts.map +1 -0
  144. package/dist/security-headers.js +121 -0
  145. package/dist/security-headers.js.map +1 -0
  146. package/dist/server-fn.d.ts +323 -0
  147. package/dist/server-fn.d.ts.map +1 -0
  148. package/dist/server-fn.js +373 -0
  149. package/dist/server-fn.js.map +1 -0
  150. package/dist/server-public.d.ts +13 -0
  151. package/dist/server-public.d.ts.map +1 -0
  152. package/dist/server-public.js +12 -0
  153. package/dist/server-public.js.map +1 -0
  154. package/dist/server-timeout.d.ts +38 -0
  155. package/dist/server-timeout.d.ts.map +1 -0
  156. package/dist/server-timeout.js +46 -0
  157. package/dist/server-timeout.js.map +1 -0
  158. package/dist/server.d.ts +100 -0
  159. package/dist/server.d.ts.map +1 -0
  160. package/dist/server.js +1218 -0
  161. package/dist/server.js.map +1 -0
  162. package/dist/socket-router.d.ts +153 -0
  163. package/dist/socket-router.d.ts.map +1 -0
  164. package/dist/socket-router.js +612 -0
  165. package/dist/socket-router.js.map +1 -0
  166. package/dist/sso.d.ts +90 -0
  167. package/dist/sso.d.ts.map +1 -0
  168. package/dist/sso.js +261 -0
  169. package/dist/sso.js.map +1 -0
  170. package/dist/ssr-context.d.ts +49 -0
  171. package/dist/ssr-context.d.ts.map +1 -0
  172. package/dist/ssr-context.js +85 -0
  173. package/dist/ssr-context.js.map +1 -0
  174. package/dist/ssr-globals.d.ts +32 -0
  175. package/dist/ssr-globals.d.ts.map +1 -0
  176. package/dist/ssr-globals.js +1010 -0
  177. package/dist/ssr-globals.js.map +1 -0
  178. package/dist/ssr-template.d.ts +73 -0
  179. package/dist/ssr-template.d.ts.map +1 -0
  180. package/dist/ssr-template.js +507 -0
  181. package/dist/ssr-template.js.map +1 -0
  182. package/dist/stack-mapper.d.ts +25 -0
  183. package/dist/stack-mapper.d.ts.map +1 -0
  184. package/dist/stack-mapper.js +139 -0
  185. package/dist/stack-mapper.js.map +1 -0
  186. package/dist/stream.d.ts +89 -0
  187. package/dist/stream.d.ts.map +1 -0
  188. package/dist/stream.js +299 -0
  189. package/dist/stream.js.map +1 -0
  190. package/dist/upload.d.ts +69 -0
  191. package/dist/upload.d.ts.map +1 -0
  192. package/dist/upload.js +110 -0
  193. package/dist/upload.js.map +1 -0
  194. package/dist/validate.d.ts +58 -0
  195. package/dist/validate.d.ts.map +1 -0
  196. package/dist/validate.js +89 -0
  197. package/dist/validate.js.map +1 -0
  198. package/dist/verify-package.d.ts +3 -0
  199. package/dist/verify-package.d.ts.map +1 -0
  200. package/dist/verify-package.js +128 -0
  201. package/dist/verify-package.js.map +1 -0
  202. package/package.json +79 -0
@@ -0,0 +1,1010 @@
1
+ /**
2
+ * mates-fullstack — ssr-globals.ts
3
+ *
4
+ * Install stateless no-op browser global stubs ONCE at boot.
5
+ *
6
+ * Why this exists:
7
+ * lit-html reads `const r = document` at module parse time.
8
+ * Mates CSS-in-JS calls `document.adoptedStyleSheets` at module init.
9
+ * Mates calls `customElements.define("x-view", ...)` at module init.
10
+ * User code may accidentally read `window.innerWidth` outside `onMount`.
11
+ *
12
+ * Without stubs, importing mates in a pure Node.js environment throws
13
+ * "document is not defined".
14
+ *
15
+ * Design rules:
16
+ * - Set ONCE at boot — never swapped per request (unlike happy-dom).
17
+ * - Stateless — every stub returns a predictable no-op value.
18
+ * No internal maps, no accumulation, no side effects.
19
+ * - Idempotent — safe to call multiple times.
20
+ * - Only sets globals that are undefined — won't overwrite a real browser or
21
+ * a happy-dom window if one is already present.
22
+ * - Not a full polyfill — just enough to prevent crashes.
23
+ *
24
+ * App code that needs real values during SSR should use isSSR() guards:
25
+ * const width = isSSR() ? 1024 : window.innerWidth;
26
+ */
27
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
28
+ const noop = () => { };
29
+ const noopReturn = (v) => () => v;
30
+ // ─── Comprehensive mock element factory ──────────────────────────────────────
31
+ //
32
+ // Returns an object that satisfies most common DOM Element property accesses.
33
+ // All methods are no-ops. All getters return null/0/[] as appropriate.
34
+ // The object is NOT an instance of any class — it's a plain object with
35
+ // duck-typed DOM properties. This is intentional: instanceof checks are
36
+ // handled by the separate class stubs (e.g., HTMLElementStub).
37
+ //
38
+ // document.createElement() returns one of these. Custom element constructors
39
+ // (like x-x's Component) create their own instances via `extends HTMLElement`.
40
+ const _mockNodeProto = {
41
+ // Node properties
42
+ nodeType: 1,
43
+ nodeName: "DIV",
44
+ tagName: "DIV",
45
+ baseURI: "http://localhost/",
46
+ ownerDocument: null,
47
+ parentNode: null,
48
+ parentElement: null,
49
+ childNodes: [],
50
+ children: [],
51
+ firstChild: null,
52
+ lastChild: null,
53
+ nextSibling: null,
54
+ previousSibling: null,
55
+ textContent: "",
56
+ nodeValue: null,
57
+ isConnected: false,
58
+ // Element properties
59
+ innerHTML: "",
60
+ outerHTML: "",
61
+ id: "",
62
+ className: "",
63
+ classList: {
64
+ add: noop,
65
+ remove: noop,
66
+ contains: noopReturn(false),
67
+ toggle: noopReturn(false),
68
+ replace: noop,
69
+ item: noopReturn(null),
70
+ entries: noopReturn([]),
71
+ keys: noopReturn([]),
72
+ values: noopReturn([]),
73
+ forEach: noop,
74
+ length: 0,
75
+ toString: noopReturn(""),
76
+ value: "",
77
+ },
78
+ style: {},
79
+ dataset: {},
80
+ attributes: { length: 0 },
81
+ tabIndex: -1,
82
+ dir: "",
83
+ hidden: false,
84
+ lang: "",
85
+ title: "",
86
+ slot: "",
87
+ scrollTop: 0,
88
+ scrollLeft: 0,
89
+ scrollWidth: 0,
90
+ scrollHeight: 0,
91
+ clientTop: 0,
92
+ clientLeft: 0,
93
+ clientWidth: 0,
94
+ clientHeight: 0,
95
+ offsetTop: 0,
96
+ offsetLeft: 0,
97
+ offsetWidth: 0,
98
+ offsetHeight: 0,
99
+ offsetParent: null,
100
+ localName: "div",
101
+ namespaceURI: "http://www.w3.org/1999/xhtml",
102
+ prefix: null,
103
+ // Content for <template> elements — should be a DocumentFragment
104
+ content: null,
105
+ // Methods
106
+ setAttribute: noop,
107
+ getAttribute: noopReturn(null),
108
+ getAttributeNames: noopReturn([]),
109
+ hasAttribute: noopReturn(false),
110
+ hasAttributes: noopReturn(false),
111
+ removeAttribute: noop,
112
+ toggleAttribute: noopReturn(false),
113
+ setAttributeNS: noop,
114
+ getAttributeNS: noopReturn(null),
115
+ removeAttributeNS: noop,
116
+ addEventListener: noop,
117
+ removeEventListener: noop,
118
+ dispatchEvent: noopReturn(false),
119
+ appendChild: function (child) {
120
+ this.childNodes.push(child);
121
+ if (this.children)
122
+ this.children.push(child);
123
+ child.parentNode = this;
124
+ return child;
125
+ },
126
+ removeChild: function (child) {
127
+ const idx = this.childNodes.indexOf(child);
128
+ if (idx !== -1)
129
+ this.childNodes.splice(idx, 1);
130
+ return child;
131
+ },
132
+ insertBefore: function (child, _ref) {
133
+ this.childNodes.push(child);
134
+ child.parentNode = this;
135
+ return child;
136
+ },
137
+ replaceChild: function (child, old) {
138
+ const idx = this.childNodes.indexOf(old);
139
+ if (idx !== -1)
140
+ this.childNodes.splice(idx, 1, child);
141
+ return old;
142
+ },
143
+ contains: noopReturn(false),
144
+ hasChildNodes: noopReturn(false),
145
+ cloneNode: function (_deep) {
146
+ // Shallow copy that preserves the prototype shape
147
+ return { ...this, childNodes: [], children: [] };
148
+ },
149
+ isEqualNode: noopReturn(true),
150
+ isSameNode: function (other) {
151
+ return this === other;
152
+ },
153
+ compareDocumentPosition: noopReturn(0),
154
+ normalize: noop,
155
+ closest: noopReturn(null),
156
+ matches: noopReturn(false),
157
+ querySelector: noopReturn(null),
158
+ querySelectorAll: noopReturn([]),
159
+ getElementsByTagName: noopReturn([]),
160
+ getElementsByClassName: noopReturn([]),
161
+ getElementsByName: noopReturn([]),
162
+ getBoundingClientRect: noopReturn({
163
+ x: 0,
164
+ y: 0,
165
+ width: 0,
166
+ height: 0,
167
+ top: 0,
168
+ right: 0,
169
+ bottom: 0,
170
+ left: 0,
171
+ toJSON: noopReturn(""),
172
+ }),
173
+ getClientRects: noopReturn([]),
174
+ scrollIntoView: noop,
175
+ scroll: noop,
176
+ scrollTo: noop,
177
+ scrollBy: noop,
178
+ focus: noop,
179
+ blur: noop,
180
+ click: noop,
181
+ insertAdjacentHTML: noop,
182
+ insertAdjacentElement: noopReturn(null),
183
+ insertAdjacentText: noop,
184
+ replaceWith: function (..._args) {
185
+ if (this.parentNode) {
186
+ this.parentNode.removeChild(this);
187
+ }
188
+ },
189
+ remove: function () {
190
+ if (this.parentNode) {
191
+ this.parentNode.removeChild(this);
192
+ }
193
+ },
194
+ before: noop,
195
+ after: noop,
196
+ prepend: noop,
197
+ append: noop,
198
+ attachShadow: noopReturn({ mode: "open", host: null }),
199
+ shadowRoot: null,
200
+ // Event timing
201
+ getAnimations: noopReturn(Promise.resolve([])),
202
+ animate: noopReturn(null),
203
+ // Form-related (for input elements)
204
+ value: "",
205
+ checked: false,
206
+ disabled: false,
207
+ name: "",
208
+ type: "text",
209
+ form: null,
210
+ files: null,
211
+ selectionStart: 0,
212
+ selectionEnd: 0,
213
+ validity: { valid: true },
214
+ validationMessage: "",
215
+ reportValidity: noopReturn(true),
216
+ setSelectionRange: noop,
217
+ select: noop,
218
+ // SVG properties
219
+ viewBox: null,
220
+ preserveAspectRatio: null,
221
+ toString() {
222
+ return `[object ${this.tagName || "Element"}]`;
223
+ },
224
+ };
225
+ function _makeMockNode(tagName = "DIV", namespace = "http://www.w3.org/1999/xhtml") {
226
+ const el = Object.create(_mockNodeProto);
227
+ el.nodeName = tagName;
228
+ el.tagName = tagName;
229
+ el.localName = tagName.toLowerCase();
230
+ el.namespaceURI = namespace;
231
+ el.ownerDocument = el; // circular reference
232
+ el.content = Object.create(_mockNodeProto);
233
+ el.content.ownerDocument = el;
234
+ el.content.childNodes = [];
235
+ el.content.children = [];
236
+ return el;
237
+ }
238
+ // ─── Public API ───────────────────────────────────────────────────────────────
239
+ /**
240
+ * Install stateless no-op browser global stubs.
241
+ * Call once at server startup, before importing mates or lit-html.
242
+ */
243
+ export function installSsrGlobals() {
244
+ const g = globalThis;
245
+ const mockBody = _makeMockNode();
246
+ const mockHead = _makeMockNode();
247
+ // ── document ────────────────────────────────────────────────────────────────
248
+ if (typeof g.document === "undefined") {
249
+ g.document = {
250
+ // Node creation — lit-html calls these at module parse time
251
+ createElement: (_tag) => _makeMockNode(),
252
+ createElementNS: (_ns, _tag) => _makeMockNode(),
253
+ createComment: (_data) => ({ nodeType: 8, data: _data ?? "" }),
254
+ createTextNode: (data) => ({ nodeType: 3, data: data ?? "" }),
255
+ createDocumentFragment: () => _makeMockNode(),
256
+ createAttribute: (_name) => ({ name: _name, value: "" }),
257
+ createAttributeNS: (_ns, _name) => ({
258
+ name: _name,
259
+ value: "",
260
+ }),
261
+ createRange: () => ({
262
+ setStart: noop,
263
+ setEnd: noop,
264
+ selectNode: noop,
265
+ selectNodeContents: noop,
266
+ getBoundingClientRect: noopReturn({ x: 0, y: 0, width: 0, height: 0 }),
267
+ getClientRects: noopReturn([]),
268
+ commonAncestorContainer: null,
269
+ startContainer: null,
270
+ startOffset: 0,
271
+ endContainer: null,
272
+ endOffset: 0,
273
+ collapsed: true,
274
+ toString: noopReturn(""),
275
+ cloneRange: noopReturn(null),
276
+ detach: noop,
277
+ deleteContents: noop,
278
+ extractContents: noopReturn(null),
279
+ insertNode: noop,
280
+ surroundContents: noop,
281
+ }),
282
+ createTreeWalker: () => ({
283
+ root: _makeMockNode(),
284
+ whatToShow: 0xffffffff,
285
+ filter: null,
286
+ nextNode: noopReturn(null),
287
+ previousNode: noopReturn(null),
288
+ firstChild: noopReturn(null),
289
+ lastChild: noopReturn(null),
290
+ nextSibling: noopReturn(null),
291
+ previousSibling: noopReturn(null),
292
+ parentNode: noopReturn(null),
293
+ currentNode: null,
294
+ }),
295
+ createNodeIterator: () => ({
296
+ nextNode: noopReturn(null),
297
+ previousNode: noopReturn(null),
298
+ detach: noop,
299
+ }),
300
+ createEvent: (_type) => ({
301
+ type: _type,
302
+ initEvent: noop,
303
+ preventDefault: noop,
304
+ stopPropagation: noop,
305
+ }),
306
+ createExpression: noopReturn(null),
307
+ createNSResolver: noopReturn(null),
308
+ evaluate: noopReturn(null),
309
+ // Queries
310
+ querySelector: noopReturn(null),
311
+ querySelectorAll: noopReturn([]),
312
+ getElementById: noopReturn(null),
313
+ getElementsByTagName: noopReturn([]),
314
+ getElementsByClassName: noopReturn([]),
315
+ getElementsByName: noopReturn([]),
316
+ // Selection
317
+ getSelection: noopReturn(null),
318
+ caretRangeFromPoint: noopReturn(null),
319
+ caretPositionFromPoint: noopReturn(null),
320
+ elementFromPoint: noopReturn(null),
321
+ elementsFromPoint: noopReturn([]),
322
+ // Cookie
323
+ cookie: "",
324
+ // Common properties
325
+ body: mockBody,
326
+ head: mockHead,
327
+ documentElement: _makeMockNode(),
328
+ title: "",
329
+ readyState: "complete",
330
+ URL: "http://localhost/",
331
+ documentURI: "http://localhost/",
332
+ baseURI: "http://localhost/",
333
+ compatMode: "CSS1Compat",
334
+ characterSet: "UTF-8",
335
+ charset: "UTF-8",
336
+ contentType: "text/html",
337
+ designMode: "off",
338
+ dir: "ltr",
339
+ hidden: false,
340
+ visibilityState: "visible",
341
+ lastModified: "",
342
+ referrer: "",
343
+ domain: "localhost",
344
+ location: g.location ?? {
345
+ href: "http://localhost/",
346
+ origin: "http://localhost",
347
+ pathname: "/",
348
+ search: "",
349
+ hash: "",
350
+ },
351
+ defaultView: g.window ?? null,
352
+ implementation: {
353
+ hasFeature: noopReturn(true),
354
+ createDocumentType: noopReturn(null),
355
+ createDocument: noopReturn(null),
356
+ createHTMLDocument: noopReturn(null),
357
+ },
358
+ scrollingElement: null,
359
+ activeElement: mockBody,
360
+ fullscreenElement: null,
361
+ pointerLockElement: null,
362
+ fonts: {
363
+ ready: Promise.resolve([]),
364
+ addEventListener: noop,
365
+ removeEventListener: noop,
366
+ check: noopReturn(true),
367
+ load: noopReturn(Promise.resolve([])),
368
+ },
369
+ timeline: {
370
+ currentTime: null,
371
+ },
372
+ fgColor: "",
373
+ linkColor: "",
374
+ vlinkColor: "",
375
+ alinkColor: "",
376
+ bgColor: "",
377
+ anchors: [],
378
+ applets: [],
379
+ forms: [],
380
+ images: [],
381
+ links: [],
382
+ plugins: [],
383
+ scripts: [],
384
+ styleSheets: [],
385
+ embeds: [],
386
+ // CSS-in-JS: mates calls document.adoptedStyleSheets = [..., sheet]
387
+ adoptedStyleSheets: [],
388
+ // Events
389
+ addEventListener: noop,
390
+ removeEventListener: noop,
391
+ dispatchEvent: noopReturn(false),
392
+ onload: null,
393
+ onreadystatechange: null,
394
+ onscroll: null,
395
+ onresize: null,
396
+ onclick: null,
397
+ // importNode — used by lit-html Template construction
398
+ importNode: (node, _deep) => node,
399
+ // write — legacy but sometimes used
400
+ write: noop,
401
+ writeln: noop,
402
+ open: noop,
403
+ close: noop,
404
+ clear: noop,
405
+ // focus management
406
+ hasFocus: noopReturn(false),
407
+ hasStorageAccess: noopReturn(Promise.resolve(false)),
408
+ // execCommand (deprecated but used by some editors)
409
+ execCommand: noopReturn(false),
410
+ queryCommandSupported: noopReturn(false),
411
+ queryCommandEnabled: noopReturn(false),
412
+ queryCommandState: noopReturn(false),
413
+ queryCommandValue: noopReturn(""),
414
+ };
415
+ }
416
+ // ── CSSStyleSheet ────────────────────────────────────────────────────────────
417
+ // Mates CSS-in-JS does `new CSSStyleSheet()` at module level.
418
+ if (typeof g.CSSStyleSheet === "undefined") {
419
+ g.CSSStyleSheet = class CSSStyleSheetStub {
420
+ cssRules = [];
421
+ replaceSync(_text) { }
422
+ replace(_text) {
423
+ return Promise.resolve(this);
424
+ }
425
+ insertRule(rule, index = 0) {
426
+ this.cssRules.splice(index, 0, rule);
427
+ return index;
428
+ }
429
+ deleteRule(_index) { }
430
+ };
431
+ }
432
+ // ── window ──────────────────────────────────────────────────────────────────
433
+ if (typeof g.window === "undefined") {
434
+ g.window = {
435
+ // Dimensions — sensible defaults for SSR layout calculations
436
+ innerWidth: 1024,
437
+ innerHeight: 768,
438
+ outerWidth: 1024,
439
+ outerHeight: 768,
440
+ devicePixelRatio: 1,
441
+ scrollX: 0,
442
+ scrollY: 0,
443
+ // Screen
444
+ screen: {
445
+ width: 1920,
446
+ height: 1080,
447
+ availWidth: 1920,
448
+ availHeight: 1040,
449
+ colorDepth: 24,
450
+ pixelDepth: 24,
451
+ top: 0,
452
+ left: 0,
453
+ availTop: 0,
454
+ availLeft: 0,
455
+ orientation: {
456
+ type: "landscape-primary",
457
+ angle: 0,
458
+ addEventListener: noop,
459
+ removeEventListener: noop,
460
+ dispatchEvent: noopReturn(false),
461
+ },
462
+ },
463
+ // Visual viewport
464
+ visualViewport: {
465
+ width: 1024,
466
+ height: 768,
467
+ scale: 1,
468
+ offsetLeft: 0,
469
+ offsetTop: 0,
470
+ pageLeft: 0,
471
+ pageTop: 0,
472
+ addEventListener: noop,
473
+ removeEventListener: noop,
474
+ dispatchEvent: noopReturn(false),
475
+ onresize: null,
476
+ onscroll: null,
477
+ },
478
+ // Security
479
+ origin: "http://localhost",
480
+ isSecureContext: false,
481
+ crossOriginIsolated: false,
482
+ // Location — SSR sets pathAtom explicitly; this is just a stub
483
+ location: {
484
+ href: "http://localhost/",
485
+ origin: "http://localhost",
486
+ protocol: "http:",
487
+ host: "localhost",
488
+ hostname: "localhost",
489
+ port: "",
490
+ pathname: "/",
491
+ search: "",
492
+ hash: "",
493
+ assign: noop,
494
+ replace: noop,
495
+ reload: noop,
496
+ },
497
+ // History
498
+ history: {
499
+ length: 1,
500
+ pushState: noop,
501
+ replaceState: noop,
502
+ go: noop,
503
+ back: noop,
504
+ forward: noop,
505
+ state: null,
506
+ },
507
+ // Storage
508
+ localStorage: {
509
+ getItem: noopReturn(null),
510
+ setItem: noop,
511
+ removeItem: noop,
512
+ clear: noop,
513
+ length: 0,
514
+ key: noopReturn(null),
515
+ },
516
+ sessionStorage: {
517
+ getItem: noopReturn(null),
518
+ setItem: noop,
519
+ removeItem: noop,
520
+ clear: noop,
521
+ length: 0,
522
+ key: noopReturn(null),
523
+ },
524
+ // Events
525
+ addEventListener: noop,
526
+ removeEventListener: noop,
527
+ dispatchEvent: noopReturn(false),
528
+ // Timing
529
+ requestAnimationFrame: (fn) => {
530
+ // Run on next tick so components don't block
531
+ setTimeout(fn, 0);
532
+ return 0;
533
+ },
534
+ cancelAnimationFrame: noop,
535
+ requestIdleCallback: (fn) => {
536
+ setTimeout(() => fn({ timeRemaining: () => 50, didTimeout: false }), 0);
537
+ return 0;
538
+ },
539
+ cancelIdleCallback: noop,
540
+ setTimeout: globalThis.setTimeout.bind(globalThis),
541
+ clearTimeout: globalThis.clearTimeout.bind(globalThis),
542
+ setInterval: globalThis.setInterval.bind(globalThis),
543
+ clearInterval: globalThis.clearInterval.bind(globalThis),
544
+ // Observers — no-op stubs
545
+ MutationObserver: class {
546
+ observe() { }
547
+ disconnect() { }
548
+ takeRecords() {
549
+ return [];
550
+ }
551
+ },
552
+ ResizeObserver: class {
553
+ observe() { }
554
+ disconnect() { }
555
+ unobserve() { }
556
+ },
557
+ IntersectionObserver: class {
558
+ observe() { }
559
+ disconnect() { }
560
+ unobserve() { }
561
+ },
562
+ // CSS / layout
563
+ getComputedStyle: (_el) => ({}),
564
+ matchMedia: (_query) => ({
565
+ matches: false,
566
+ media: _query,
567
+ onchange: null,
568
+ addListener: noop,
569
+ removeListener: noop,
570
+ addEventListener: noop,
571
+ removeEventListener: noop,
572
+ dispatchEvent: noopReturn(false),
573
+ }),
574
+ // Performance
575
+ performance: {
576
+ now: () => Date.now(),
577
+ mark: noop,
578
+ measure: noop,
579
+ clearMarks: noop,
580
+ clearMeasures: noop,
581
+ getEntriesByName: noopReturn([]),
582
+ getEntriesByType: noopReturn([]),
583
+ },
584
+ // Navigator
585
+ navigator: {
586
+ userAgent: "mates-ssr",
587
+ language: "en-US",
588
+ languages: ["en-US"],
589
+ onLine: true,
590
+ platform: "server",
591
+ },
592
+ // Misc
593
+ scrollTo: noop,
594
+ scrollBy: noop,
595
+ open: noopReturn(null),
596
+ close: noop,
597
+ focus: noop,
598
+ blur: noop,
599
+ alert: noop,
600
+ confirm: noopReturn(false),
601
+ prompt: noopReturn(null),
602
+ fetch: typeof fetch !== "undefined" ? fetch : undefined,
603
+ crypto: typeof crypto !== "undefined"
604
+ ? crypto
605
+ : {
606
+ getRandomValues: (arr) => arr,
607
+ randomUUID: () => "ssr-uuid",
608
+ },
609
+ // Self-reference
610
+ get self() {
611
+ return g.window;
612
+ },
613
+ get top() {
614
+ return g.window;
615
+ },
616
+ get parent() {
617
+ return g.window;
618
+ },
619
+ get globalThis() {
620
+ return g;
621
+ },
622
+ };
623
+ // Also expose window props at globalThis level (how browsers work)
624
+ if (typeof g.location === "undefined")
625
+ g.location = g.window.location;
626
+ if (typeof g.history === "undefined")
627
+ g.history = g.window.history;
628
+ if (typeof g.performance === "undefined")
629
+ g.performance = g.window.performance;
630
+ if (typeof g.navigator === "undefined")
631
+ g.navigator = g.window.navigator;
632
+ if (typeof g.localStorage === "undefined")
633
+ g.localStorage = g.window.localStorage;
634
+ if (typeof g.sessionStorage === "undefined")
635
+ g.sessionStorage = g.window.sessionStorage;
636
+ if (typeof g.screen === "undefined")
637
+ g.screen = g.window.screen;
638
+ if (typeof g.requestAnimationFrame === "undefined")
639
+ g.requestAnimationFrame = g.window.requestAnimationFrame;
640
+ if (typeof g.cancelAnimationFrame === "undefined")
641
+ g.cancelAnimationFrame = g.window.cancelAnimationFrame;
642
+ if (typeof g.MutationObserver === "undefined")
643
+ g.MutationObserver = g.window.MutationObserver;
644
+ if (typeof g.ResizeObserver === "undefined")
645
+ g.ResizeObserver = g.window.ResizeObserver;
646
+ if (typeof g.IntersectionObserver === "undefined")
647
+ g.IntersectionObserver = g.window.IntersectionObserver;
648
+ if (typeof g.matchMedia === "undefined")
649
+ g.matchMedia = g.window.matchMedia;
650
+ }
651
+ // ── customElements ──────────────────────────────────────────────────────────
652
+ if (typeof g.customElements === "undefined") {
653
+ const _registry = new Map();
654
+ g.customElements = {
655
+ get: (name) => _registry.get(name),
656
+ whenDefined: (_name) => Promise.resolve(),
657
+ upgrade: noop,
658
+ define(name, constructor, _options) {
659
+ // Silent no-op on re-registration — same guard as renderer's
660
+ // _patchCustomElementsDefine()
661
+ if (_registry.has(name))
662
+ return;
663
+ _registry.set(name, constructor);
664
+ },
665
+ };
666
+ }
667
+ else if (g.customElements && !g.customElements.__matesSSRGlobalsPatched__) {
668
+ // customElements already exists — patch define() to be silent on re-register
669
+ const orig = g.customElements.define.bind(g.customElements);
670
+ g.customElements.define = function (name, ctor, opts) {
671
+ if (g.customElements.get(name))
672
+ return;
673
+ try {
674
+ orig(name, ctor, opts);
675
+ }
676
+ catch {
677
+ /* ignore */
678
+ }
679
+ };
680
+ g.customElements.__matesSSRGlobalsPatched__ = true;
681
+ }
682
+ // ── DOM class stubs ─────────────────────────────────────────────────────────
683
+ // Mates registers x-view as `class Component extends HTMLElement`.
684
+ // Without these, `class Foo extends HTMLElement` throws.
685
+ // Custom element constructors create instances via `class extends HTMLElement`,
686
+ // not via `document.createElement()`. The mock elements from _makeMockNode()
687
+ // are plain objects — they don't extend HTMLElementStub. This is correct
688
+ // because: (a) custom elements get their prototype from the class, not from
689
+ // createElement, and (b) plain objects are sufficient for SSR since no DOM
690
+ // operations actually execute.
691
+ if (typeof g.HTMLElement === "undefined") {
692
+ g.HTMLElement = class HTMLElementStub {
693
+ // ── Node identity ────────────────────────────────────────────────────
694
+ nodeType = 1;
695
+ nodeName = "";
696
+ tagName = "";
697
+ baseURI = "http://localhost/";
698
+ ownerDocument = null;
699
+ parentNode = null;
700
+ parentElement = null;
701
+ childNodes = [];
702
+ children = [];
703
+ firstChild = null;
704
+ lastChild = null;
705
+ nextSibling = null;
706
+ previousSibling = null;
707
+ textContent = "";
708
+ nodeValue = null;
709
+ isConnected = false;
710
+ // ── Element content ──────────────────────────────────────────────────
711
+ innerHTML = "";
712
+ outerHTML = "";
713
+ id = "";
714
+ className = "";
715
+ classList = {
716
+ add: noop,
717
+ remove: noop,
718
+ contains: noopReturn(false),
719
+ toggle: noopReturn(false),
720
+ replace: noop,
721
+ item: noopReturn(null),
722
+ addEventListener: noop,
723
+ removeEventListener: noop,
724
+ forEach: noop,
725
+ length: 0,
726
+ toString: noopReturn(""),
727
+ value: "",
728
+ };
729
+ style = {};
730
+ dataset = {};
731
+ attributes = { length: 0 };
732
+ tabIndex = -1;
733
+ dir = "";
734
+ hidden = false;
735
+ lang = "";
736
+ slot = "";
737
+ scrollTop = 0;
738
+ scrollLeft = 0;
739
+ offsetTop = 0;
740
+ offsetLeft = 0;
741
+ offsetWidth = 0;
742
+ offsetHeight = 0;
743
+ offsetParent = null;
744
+ localName = "";
745
+ namespaceURI = "http://www.w3.org/1999/xhtml";
746
+ prefix = null;
747
+ // ── Accessibility ────────────────────────────────────────────────────
748
+ role = null;
749
+ ariaLabel = null;
750
+ ariaHidden = null;
751
+ // ── Shadow DOM ────────────────────────────────────────────────────────
752
+ shadowRoot = null;
753
+ // ── Methods ────────────────────────────────────────────────────────────
754
+ addEventListener = noop;
755
+ removeEventListener = noop;
756
+ dispatchEvent = noopReturn(false);
757
+ setAttribute = noop;
758
+ getAttribute = noopReturn(null);
759
+ getAttributeNames = noopReturn([]);
760
+ hasAttribute = noopReturn(false);
761
+ hasAttributes = noopReturn(false);
762
+ removeAttribute = noop;
763
+ toggleAttribute = noopReturn(false);
764
+ appendChild = function (child) {
765
+ this.childNodes.push(child);
766
+ this.children.push(child);
767
+ child.parentNode = this;
768
+ return child;
769
+ };
770
+ removeChild = function (child) {
771
+ const idx = this.childNodes.indexOf(child);
772
+ if (idx !== -1)
773
+ this.childNodes.splice(idx, 1);
774
+ return child;
775
+ };
776
+ insertBefore = function (child, _ref) {
777
+ this.childNodes.push(child);
778
+ child.parentNode = this;
779
+ return child;
780
+ };
781
+ replaceChild = function (child, old) {
782
+ const idx = this.childNodes.indexOf(old);
783
+ if (idx !== -1)
784
+ this.childNodes.splice(idx, 1, child);
785
+ return old;
786
+ };
787
+ contains = noopReturn(false);
788
+ hasChildNodes = noopReturn(false);
789
+ cloneNode = function (_deep) {
790
+ return { ...this, childNodes: [], children: [] };
791
+ };
792
+ isEqualNode = noopReturn(true);
793
+ isSameNode = function (other) {
794
+ return this === other;
795
+ };
796
+ compareDocumentPosition = noopReturn(0);
797
+ normalize = noop;
798
+ closest = noopReturn(null);
799
+ matches = noopReturn(false);
800
+ querySelector = noopReturn(null);
801
+ querySelectorAll = noopReturn([]);
802
+ getElementsByTagName = noopReturn([]);
803
+ getElementsByClassName = noopReturn([]);
804
+ getBoundingClientRect = noopReturn({
805
+ x: 0,
806
+ y: 0,
807
+ width: 0,
808
+ height: 0,
809
+ top: 0,
810
+ right: 0,
811
+ bottom: 0,
812
+ left: 0,
813
+ toJSON: noopReturn(""),
814
+ });
815
+ getClientRects = noopReturn([]);
816
+ scrollIntoView = noop;
817
+ scroll = noop;
818
+ scrollTo = noop;
819
+ scrollBy = noop;
820
+ focus = noop;
821
+ blur = noop;
822
+ click = noop;
823
+ insertAdjacentHTML = noop;
824
+ insertAdjacentElement = noopReturn(null);
825
+ insertAdjacentText = noop;
826
+ replaceWith = noop;
827
+ remove = noop;
828
+ before = noop;
829
+ after = noop;
830
+ prepend = noop;
831
+ append = noop;
832
+ attachShadow = function (_init) {
833
+ const root = { mode: _init?.mode ?? "open", host: this, innerHTML: "" };
834
+ this.shadowRoot = root;
835
+ return root;
836
+ };
837
+ getAnimations = noopReturn(Promise.resolve([]));
838
+ animate = noopReturn(null);
839
+ // Form element properties (for input-like elements)
840
+ value = "";
841
+ checked = false;
842
+ disabled = false;
843
+ name = "";
844
+ type = "text";
845
+ form = null;
846
+ files = null;
847
+ validity = { valid: true };
848
+ validationMessage = "";
849
+ reportValidity = noopReturn(true);
850
+ setSelectionRange = noop;
851
+ select = noop;
852
+ toString() {
853
+ return `[object ${this.tagName || "Element"}]`;
854
+ }
855
+ };
856
+ }
857
+ // ── Element subclass stubs ─────────────────────────────────────────────────
858
+ // These exist so that `element instanceof HTMLDivElement` doesn't throw.
859
+ // They share HTMLElementStub's prototype — no separate behavior needed.
860
+ const HTML_CTORS = [
861
+ "HTMLDivElement",
862
+ "HTMLSpanElement",
863
+ "HTMLParagraphElement",
864
+ "HTMLAnchorElement",
865
+ "HTMLImageElement",
866
+ "HTMLInputElement",
867
+ "HTMLButtonElement",
868
+ "HTMLFormElement",
869
+ "HTMLTextAreaElement",
870
+ "HTMLSelectElement",
871
+ "HTMLOptionElement",
872
+ "HTMLLIElement",
873
+ "HTMLUListElement",
874
+ "HTMLOListElement",
875
+ "HTMLTableElement",
876
+ "HTMLTableRowElement",
877
+ "HTMLTableCellElement",
878
+ "HTMLHeadingElement",
879
+ "HTMLBRElement",
880
+ "HTMLHRElement",
881
+ "HTMLTemplateElement",
882
+ "HTMLCanvasElement",
883
+ "HTMLVideoElement",
884
+ "HTMLAudioElement",
885
+ "HTMLSourceElement",
886
+ "HTMLScriptElement",
887
+ "HTMLStyleElement",
888
+ "HTMLLinkElement",
889
+ "HTMLMetaElement",
890
+ "HTMLTitleElement",
891
+ "HTMLHeadElement",
892
+ "HTMLBodyElement",
893
+ "HTMLHtmlElement",
894
+ "HTMLIFrameElement",
895
+ "HTMLLabelElement",
896
+ "HTMLFieldSetElement",
897
+ "HTMLLegendElement",
898
+ "HTMLDataListElement",
899
+ "HTMLProgressElement",
900
+ "HTMLMeterElement",
901
+ "HTMLSlotElement",
902
+ "HTMLDetailsElement",
903
+ "HTMLDialogElement",
904
+ "HTMLMenuElement",
905
+ "HTMLUnknownElement",
906
+ "SVGSVGElement",
907
+ "SVGCircleElement",
908
+ "SVGRectElement",
909
+ "SVGLineElement",
910
+ "SVGPathElement",
911
+ "SVGTextElement",
912
+ "SVGGElement",
913
+ "SVGDefsElement",
914
+ "SVGUseElement",
915
+ "SVGImageElement",
916
+ "SVGSymbolElement",
917
+ ];
918
+ for (const name of HTML_CTORS) {
919
+ if (typeof g[name] === "undefined") {
920
+ g[name] = g.HTMLElement;
921
+ }
922
+ }
923
+ if (typeof g.SVGElement === "undefined")
924
+ g.SVGElement = g.HTMLElement;
925
+ if (typeof g.Element === "undefined")
926
+ g.Element = g.HTMLElement;
927
+ if (typeof g.DocumentFragment === "undefined") {
928
+ g.DocumentFragment = g.HTMLElement;
929
+ }
930
+ if (typeof g.Text === "undefined") {
931
+ g.Text = class TextStub {
932
+ nodeType = 3;
933
+ nodeName = "#text";
934
+ data = "";
935
+ textContent = "";
936
+ wholeText = "";
937
+ splitText = noopReturn({});
938
+ replaceWholeText = noop;
939
+ };
940
+ }
941
+ if (typeof g.Comment === "undefined") {
942
+ g.Comment = class CommentStub {
943
+ nodeType = 8;
944
+ nodeName = "#comment";
945
+ data = "";
946
+ textContent = "";
947
+ };
948
+ }
949
+ if (typeof g.DOMParser === "undefined") {
950
+ g.DOMParser = class DOMParserStub {
951
+ parseFromString() {
952
+ return g.document ?? { querySelector: noopReturn(null) };
953
+ }
954
+ };
955
+ }
956
+ if (typeof g.Node === "undefined") {
957
+ g.Node = class NodeStub {
958
+ };
959
+ g.Node.ELEMENT_NODE = 1;
960
+ g.Node.TEXT_NODE = 3;
961
+ g.Node.COMMENT_NODE = 8;
962
+ g.Node.DOCUMENT_FRAGMENT_NODE = 11;
963
+ g.Node.DOCUMENT_POSITION_DISCONNECTED = 1;
964
+ g.Node.DOCUMENT_POSITION_PRECEDING = 2;
965
+ g.Node.DOCUMENT_POSITION_FOLLOWING = 4;
966
+ g.Node.DOCUMENT_POSITION_CONTAINS = 8;
967
+ g.Node.DOCUMENT_POSITION_CONTAINED_BY = 16;
968
+ g.Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
969
+ }
970
+ if (typeof g.NodeFilter === "undefined") {
971
+ g.NodeFilter = {
972
+ SHOW_ALL: 0xffffffff,
973
+ SHOW_ELEMENT: 1,
974
+ SHOW_TEXT: 4,
975
+ SHOW_COMMENT: 128,
976
+ SHOW_DOCUMENT: 256,
977
+ SHOW_DOCUMENT_FRAGMENT: 1024,
978
+ FILTER_ACCEPT: 1,
979
+ FILTER_REJECT: 2,
980
+ FILTER_SKIP: 3,
981
+ };
982
+ }
983
+ // ── Event classes ────────────────────────────────────────────────────────────
984
+ if (typeof g.Event === "undefined") {
985
+ g.Event = class EventStub {
986
+ type;
987
+ bubbles;
988
+ cancelable;
989
+ defaultPrevented = false;
990
+ stopPropagation = noop;
991
+ preventDefault = noop;
992
+ stopImmediatePropagation = noop;
993
+ constructor(type, opts) {
994
+ this.type = type;
995
+ this.bubbles = opts?.bubbles ?? false;
996
+ this.cancelable = opts?.cancelable ?? false;
997
+ }
998
+ };
999
+ }
1000
+ if (typeof g.CustomEvent === "undefined") {
1001
+ g.CustomEvent = class CustomEventStub extends g.Event {
1002
+ detail;
1003
+ constructor(type, opts) {
1004
+ super(type, opts);
1005
+ this.detail = opts?.detail ?? null;
1006
+ }
1007
+ };
1008
+ }
1009
+ }
1010
+ //# sourceMappingURL=ssr-globals.js.map