@webjourney/vite-plugins 1.2.11-0 → 1.2.13

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.
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,iBA+C5D"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,iBA+C5D"}
package/dist/build.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { match as matchMedia } from 'css-mediaquery';
1
2
  import { JSDOM } from 'jsdom';
2
3
  import { execSync } from 'node:child_process';
3
4
  import fs from 'node:fs';
@@ -39,54 +40,20 @@ export const render = createServerRenderer(App);
39
40
  }
40
41
  }
41
42
  }
42
- async function extractRoutes(projectRoot) {
43
- const toAbsolute = (p) => path.resolve(projectRoot, p);
44
- // Import App component from the built SSR bundle
45
- const entryServerPath = toAbsolute('dist-ssr/.webjourney-entry-server.js');
46
- const { App } = await import(entryServerPath);
47
- // Create a temporary React element to traverse
48
- const appElement = App();
49
- // Extract routes by traversing the React element tree
50
- const routes = [];
51
- function traverseElement(element) {
52
- if (!element)
53
- return;
54
- // Check if this is a Route component with a path prop
55
- if (element.type?.name === 'Route' || element.type?.displayName === 'Route') {
56
- const path = element.props?.path;
57
- if (path && typeof path === 'string') {
58
- routes.push(path);
59
- }
60
- }
61
- // Traverse children
62
- if (element.props?.children) {
63
- const children = Array.isArray(element.props.children)
64
- ? element.props.children
65
- : [element.props.children];
66
- children.forEach((child) => {
67
- if (child && typeof child === 'object') {
68
- traverseElement(child);
69
- }
70
- });
71
- }
72
- }
73
- traverseElement(appElement);
74
- // If no routes found, default to root
75
- return routes.length > 0 ? routes : ['/'];
76
- }
77
- async function prerender(projectRoot) {
78
- const toAbsolute = (p) => path.resolve(projectRoot, p);
79
- // Read the built index.html
80
- const templatePath = toAbsolute('dist/index.html');
81
- const template = fs.readFileSync(templatePath, 'utf-8');
43
+ function setupSSREnvironment() {
44
+ console.log('Setting up SSR environment...');
82
45
  // Setup JSDOM for React rendering
83
46
  const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', {
84
47
  url: 'http://localhost',
48
+ pretendToBeVisual: true,
85
49
  });
86
- // Setup globals for React SSR
50
+ // Save original globals
87
51
  const originalWindow = global.window;
88
52
  const originalDocument = global.document;
53
+ const originalRequestAnimationFrame = globalThis.requestAnimationFrame;
54
+ const originalCancelAnimationFrame = globalThis.cancelAnimationFrame;
89
55
  const originalConsoleError = console.error;
56
+ // Setup window and document globals
90
57
  Object.defineProperty(global, 'window', {
91
58
  writable: true,
92
59
  configurable: true,
@@ -97,6 +64,32 @@ async function prerender(projectRoot) {
97
64
  configurable: true,
98
65
  value: dom.window.document,
99
66
  });
67
+ // Polyfill requestAnimationFrame/cancelAnimationFrame on globalThis for SSR
68
+ // JSDOM provides these on window with pretendToBeVisual, but libraries like GSAP need them on globalThis
69
+ if (typeof globalThis.requestAnimationFrame === 'undefined') {
70
+ globalThis.requestAnimationFrame = dom.window.requestAnimationFrame.bind(dom.window);
71
+ }
72
+ if (typeof globalThis.cancelAnimationFrame === 'undefined') {
73
+ globalThis.cancelAnimationFrame = dom.window.cancelAnimationFrame.bind(dom.window);
74
+ }
75
+ // Polyfill window.matchMedia for SSR (JSDOM doesn't provide this)
76
+ if (typeof dom.window.matchMedia === 'undefined') {
77
+ dom.window.matchMedia = (query) => {
78
+ return {
79
+ matches: matchMedia(query, {
80
+ width: dom.window.innerWidth || 1024,
81
+ height: dom.window.innerHeight || 768,
82
+ }),
83
+ media: query,
84
+ onchange: null,
85
+ addListener: () => { }, // deprecated
86
+ removeListener: () => { }, // deprecated
87
+ addEventListener: () => { },
88
+ removeEventListener: () => { },
89
+ dispatchEvent: () => true,
90
+ };
91
+ };
92
+ }
100
93
  // Track if we're in a warning block (for multi-line warnings with stack traces)
101
94
  let suppressingWarning = false;
102
95
  // Suppress known SSR warnings from React and Radix UI
@@ -123,6 +116,81 @@ async function prerender(projectRoot) {
123
116
  originalConsoleError(...args);
124
117
  }
125
118
  };
119
+ // Return cleanup function
120
+ const cleanup = () => {
121
+ console.log('Cleaning up SSR environment...');
122
+ console.error = originalConsoleError;
123
+ if (originalWindow !== undefined) {
124
+ global.window = originalWindow;
125
+ }
126
+ else {
127
+ delete global.window;
128
+ }
129
+ if (originalDocument !== undefined) {
130
+ global.document = originalDocument;
131
+ }
132
+ else {
133
+ delete global.document;
134
+ }
135
+ if (originalRequestAnimationFrame !== undefined) {
136
+ globalThis.requestAnimationFrame = originalRequestAnimationFrame;
137
+ }
138
+ else {
139
+ delete globalThis.requestAnimationFrame;
140
+ }
141
+ if (originalCancelAnimationFrame !== undefined) {
142
+ globalThis.cancelAnimationFrame = originalCancelAnimationFrame;
143
+ }
144
+ else {
145
+ delete globalThis.cancelAnimationFrame;
146
+ }
147
+ console.log('SSR environment cleanup complete');
148
+ };
149
+ console.log('SSR environment setup complete');
150
+ return { dom, cleanup };
151
+ }
152
+ async function extractRoutes(projectRoot) {
153
+ const toAbsolute = (p) => path.resolve(projectRoot, p);
154
+ // Import App component from the built SSR bundle
155
+ const entryServerPath = toAbsolute('dist-ssr/.webjourney-entry-server.js');
156
+ const { App } = await import(entryServerPath);
157
+ // Create a temporary React element to traverse
158
+ const appElement = App();
159
+ // Extract routes by traversing the React element tree
160
+ const routes = [];
161
+ function traverseElement(element) {
162
+ if (!element)
163
+ return;
164
+ // Check if this is a Route component with a path prop
165
+ if (element.type?.name === 'Route' || element.type?.displayName === 'Route') {
166
+ const path = element.props?.path;
167
+ if (path && typeof path === 'string') {
168
+ routes.push(path);
169
+ }
170
+ }
171
+ // Traverse children
172
+ if (element.props?.children) {
173
+ const children = Array.isArray(element.props.children)
174
+ ? element.props.children
175
+ : [element.props.children];
176
+ children.forEach((child) => {
177
+ if (child && typeof child === 'object') {
178
+ traverseElement(child);
179
+ }
180
+ });
181
+ }
182
+ }
183
+ traverseElement(appElement);
184
+ // If no routes found, default to root
185
+ return routes.length > 0 ? routes : ['/'];
186
+ }
187
+ async function prerender(projectRoot) {
188
+ const toAbsolute = (p) => path.resolve(projectRoot, p);
189
+ // Read the built index.html
190
+ const templatePath = toAbsolute('dist/index.html');
191
+ const template = fs.readFileSync(templatePath, 'utf-8');
192
+ // Setup SSR environment with all necessary polyfills
193
+ const { cleanup } = setupSSREnvironment();
126
194
  // Import the server entry after setting up globals
127
195
  const entryServerPath = toAbsolute('dist-ssr/.webjourney-entry-server.js');
128
196
  const { render } = await import(entryServerPath);
@@ -162,19 +230,7 @@ async function prerender(projectRoot) {
162
230
  await new Promise(resolve => setTimeout(resolve, 10));
163
231
  }
164
232
  finally {
165
- // Clean up - always restore console methods even if there's an error
166
- console.error = originalConsoleError;
167
- if (originalWindow !== undefined) {
168
- global.window = originalWindow;
169
- }
170
- else {
171
- delete global.window;
172
- }
173
- if (originalDocument !== undefined) {
174
- global.document = originalDocument;
175
- }
176
- else {
177
- delete global.document;
178
- }
233
+ // Clean up - restore all globals to their original state
234
+ cleanup();
179
235
  }
180
236
  }
package/dist/cli.js CHANGED
@@ -1,12 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { buildWithSSR } from './build.js';
3
3
  async function main() {
4
+ const startTime = performance.now();
4
5
  try {
5
6
  await buildWithSSR();
6
7
  }
7
8
  catch (err) {
8
- console.error('Build failed:', err);
9
+ const duration = ((performance.now() - startTime) / 1000).toFixed(2);
10
+ console.error(`Build failed after ${duration}s:`, err);
9
11
  process.exit(1);
10
12
  }
13
+ const duration = ((performance.now() - startTime) / 1000).toFixed(0);
14
+ console.log(`Build success after ${duration}s`);
15
+ process.exit(0);
11
16
  }
12
17
  main();
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB;;;oBAKnB,MAAM,MAAM,MAAM;;;;EAkSrC;AAED,wBAAgB,sBAAsB;;;6BAKT,MAAM;EAoBlC;AAED,wBAAgB,iBAAiB;;;oBA/Tb,MAAM,MAAM,MAAM;;;;;;;6BAyST,MAAM;KA0BlC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB;;;oBAKnB,MAAM,MAAM,MAAM;;;;EAsUrC;AAED,wBAAgB,sBAAsB;;;6BAKT,MAAM;EAoBlC;AAED,wBAAgB,iBAAiB;;;oBAnWb,MAAM,MAAM,MAAM;;;;;;;6BA6UT,MAAM;KA0BlC"}
package/dist/index.js CHANGED
@@ -159,6 +159,20 @@ export function webjourneyElementTagger() {
159
159
  modified = true;
160
160
  }
161
161
  }
162
+ // Handle all remaining div elements as 'frame' type
163
+ // This catches divs that weren't marked by other conditions
164
+ if (tagName === 'div') {
165
+ // Check again if data-wj-file was added by previous conditions
166
+ const hasDataWjNow = openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
167
+ t.isJSXIdentifier(attr.name) &&
168
+ attr.name.name === 'data-wj-file');
169
+ if (!hasDataWjNow) {
170
+ // This div wasn't marked by any other condition, mark it as 'frame'
171
+ const elementId = `${relativePath}:${lineNumber}`;
172
+ openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('data-wj-file'), t.stringLiteral(relativePath)), t.jsxAttribute(t.jsxIdentifier('data-wj-line'), t.stringLiteral(String(lineNumber))), t.jsxAttribute(t.jsxIdentifier('data-wj-type'), t.stringLiteral('frame')), t.jsxAttribute(t.jsxIdentifier('data-wj-id'), t.stringLiteral(elementId)));
173
+ modified = true;
174
+ }
175
+ }
162
176
  }
163
177
  });
164
178
  if (modified) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjourney/vite-plugins",
3
- "version": "1.2.11-0",
3
+ "version": "1.2.13",
4
4
  "description": "Vite plugins for Webjourney WYSIWYG editing",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,12 +35,14 @@
35
35
  "@babel/parser": "^7.26.5",
36
36
  "@babel/traverse": "^7.26.5",
37
37
  "@babel/types": "^7.26.5",
38
+ "css-mediaquery": "^0.1.2",
38
39
  "jsdom": "^26.1.0"
39
40
  },
40
41
  "devDependencies": {
41
42
  "@types/babel__generator": "^7.6.8",
42
43
  "@types/babel__traverse": "^7.20.6",
43
- "@types/jsdom": "^21.1.7",
44
+ "@types/css-mediaquery": "^0.1.4",
45
+ "@types/jsdom": "^27.0.0",
44
46
  "@types/node": "^20.0.0",
45
47
  "@types/react": "^18.0.0",
46
48
  "@types/react-dom": "^18.0.0",