@plumeria/turbopack-loader 3.0.1 → 4.0.0

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 (2) hide show
  1. package/dist/index.js +276 -75
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -9,6 +9,10 @@ const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const zss_engine_1 = require("zss-engine");
11
11
  const utils_1 = require("@plumeria/utils");
12
+ const VIRTUAL_FILE_PATH = path_1.default.resolve(__dirname, '..', 'zero-virtual.css');
13
+ if (process.env.NODE_ENV === 'production') {
14
+ fs_1.default.writeFileSync(VIRTUAL_FILE_PATH, '/** Placeholder file */', 'utf-8');
15
+ }
12
16
  async function loader(source) {
13
17
  const callback = this.async();
14
18
  if (this.resourcePath.includes('node_modules') ||
@@ -34,38 +38,109 @@ async function loader(source) {
34
38
  });
35
39
  const localConsts = (0, utils_1.collectLocalConsts)(ast);
36
40
  Object.assign(utils_1.tables.staticTable, localConsts);
41
+ const isTSFile = this.resourcePath.endsWith('.ts') && !this.resourcePath.endsWith('.tsx');
37
42
  const localCreateStyles = {};
38
43
  const replacements = [];
39
44
  const extractedSheets = [];
40
- (0, utils_1.traverse)(ast, {
41
- VariableDeclarator({ node }) {
42
- if (node.id.type === 'Identifier' &&
43
- node.init &&
44
- utils_1.t.isCallExpression(node.init) &&
45
- utils_1.t.isMemberExpression(node.init.callee) &&
46
- utils_1.t.isIdentifier(node.init.callee.object, { name: 'css' }) &&
47
- utils_1.t.isIdentifier(node.init.callee.property, { name: 'create' }) &&
48
- node.init.arguments.length === 1 &&
45
+ const processedDecls = new Set();
46
+ const excludedSpans = new Set();
47
+ const idSpans = new Set();
48
+ const registerStyle = (node, declSpan, isExported) => {
49
+ if (utils_1.t.isIdentifier(node.id) &&
50
+ node.init &&
51
+ utils_1.t.isCallExpression(node.init) &&
52
+ utils_1.t.isMemberExpression(node.init.callee) &&
53
+ utils_1.t.isIdentifier(node.init.callee.object, { name: 'css' }) &&
54
+ utils_1.t.isIdentifier(node.init.callee.property) &&
55
+ node.init.arguments.length >= 1) {
56
+ const propName = node.init.callee.property.value;
57
+ if (propName === 'create' &&
49
58
  utils_1.t.isObjectExpression(node.init.arguments[0].expression)) {
50
59
  const obj = (0, utils_1.objectExpressionToObject)(node.init.arguments[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
51
60
  if (obj) {
52
- localCreateStyles[node.id.value] = obj;
53
61
  const hashMap = {};
54
62
  Object.entries(obj).forEach(([key, style]) => {
55
63
  const records = (0, utils_1.getStyleRecords)(key, style, 2);
56
- const propMap = {};
57
64
  (0, utils_1.extractOndemandStyles)(style, extractedSheets);
58
65
  records.forEach((r) => {
59
- propMap[r.key] = r.hash;
60
66
  extractedSheets.push(r.sheet);
61
67
  });
62
- hashMap[key] = records.map((r) => r.hash).join(' ');
68
+ const atomMap = {};
69
+ records.forEach((r) => (atomMap[r.key] = r.hash));
70
+ hashMap[key] = atomMap;
63
71
  });
64
- replacements.push({
72
+ if (utils_1.t.isIdentifier(node.id)) {
73
+ idSpans.add(node.id.span.start);
74
+ }
75
+ localCreateStyles[node.id.value] = {
76
+ name: node.id.value,
77
+ type: 'create',
78
+ obj,
79
+ hashMap,
80
+ hasDynamicAccess: false,
81
+ isExported,
82
+ initSpan: {
83
+ start: node.init.span.start - ast.span.start,
84
+ end: node.init.span.end - ast.span.start,
85
+ },
86
+ declSpan: {
87
+ start: declSpan.start - ast.span.start,
88
+ end: declSpan.end - ast.span.start,
89
+ },
90
+ };
91
+ }
92
+ }
93
+ else if ((propName === 'createTheme' || propName === 'createStatic') &&
94
+ (utils_1.t.isObjectExpression(node.init.arguments[0].expression) ||
95
+ utils_1.t.isStringLiteral(node.init.arguments[0].expression))) {
96
+ localCreateStyles[node.id.value] = {
97
+ name: node.id.value,
98
+ type: 'constant',
99
+ obj: {},
100
+ hashMap: {},
101
+ hasDynamicAccess: false,
102
+ isExported,
103
+ initSpan: {
65
104
  start: node.init.span.start - ast.span.start,
66
105
  end: node.init.span.end - ast.span.start,
67
- content: JSON.stringify(hashMap),
68
- });
106
+ },
107
+ declSpan: {
108
+ start: declSpan.start - ast.span.start,
109
+ end: declSpan.end - ast.span.start,
110
+ },
111
+ };
112
+ }
113
+ }
114
+ };
115
+ (0, utils_1.traverse)(ast, {
116
+ ExportDeclaration({ node }) {
117
+ if (utils_1.t.isVariableDeclaration(node.declaration)) {
118
+ processedDecls.add(node.declaration);
119
+ node.declaration.declarations.forEach((decl) => {
120
+ registerStyle(decl, node.span, true);
121
+ });
122
+ }
123
+ },
124
+ VariableDeclaration({ node }) {
125
+ if (processedDecls.has(node))
126
+ return;
127
+ node.declarations.forEach((decl) => {
128
+ registerStyle(decl, node.span, false);
129
+ });
130
+ },
131
+ MemberExpression({ node }) {
132
+ if (utils_1.t.isIdentifier(node.object)) {
133
+ const styleInfo = localCreateStyles[node.object.value];
134
+ if (styleInfo) {
135
+ if (utils_1.t.isIdentifier(node.property)) {
136
+ const hash = styleInfo.hashMap[node.property.value];
137
+ if (!hash && styleInfo.type !== 'constant') {
138
+ styleInfo.hasDynamicAccess = true;
139
+ }
140
+ }
141
+ else {
142
+ styleInfo.hasDynamicAccess = true;
143
+ }
69
144
  }
70
145
  }
71
146
  },
@@ -76,44 +151,7 @@ async function loader(source) {
76
151
  utils_1.t.isIdentifier(callee.property)) {
77
152
  const propName = callee.property.value;
78
153
  const args = node.arguments;
79
- if (propName === 'props') {
80
- const merged = {};
81
- let allStatic = true;
82
- args.forEach((arg) => {
83
- const expr = arg.expression;
84
- if (utils_1.t.isObjectExpression(expr)) {
85
- const obj = (0, utils_1.objectExpressionToObject)(expr, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
86
- obj ? Object.assign(merged, obj) : (allStatic = false);
87
- }
88
- else if (utils_1.t.isMemberExpression(expr) &&
89
- utils_1.t.isIdentifier(expr.object) &&
90
- utils_1.t.isIdentifier(expr.property)) {
91
- const styleSet = localCreateStyles[expr.object.value];
92
- styleSet && styleSet[expr.property.value]
93
- ? Object.assign(merged, styleSet[expr.property.value])
94
- : (allStatic = false);
95
- }
96
- else if (utils_1.t.isIdentifier(expr)) {
97
- const obj = localCreateStyles[expr.value];
98
- obj ? Object.assign(merged, obj) : (allStatic = false);
99
- }
100
- else {
101
- allStatic = false;
102
- }
103
- });
104
- if (allStatic && Object.keys(merged).length > 0) {
105
- (0, utils_1.extractOndemandStyles)(merged, extractedSheets);
106
- const hash = (0, zss_engine_1.genBase36Hash)(merged, 1, 8);
107
- const records = (0, utils_1.getStyleRecords)(hash, merged, 2);
108
- records.forEach((r) => extractedSheets.push(r.sheet));
109
- replacements.push({
110
- start: node.span.start - ast.span.start,
111
- end: node.span.end - ast.span.start,
112
- content: JSON.stringify(records.map((r) => r.hash).join(' ')),
113
- });
114
- }
115
- }
116
- else if (propName === 'keyframes' &&
154
+ if (propName === 'keyframes' &&
117
155
  args.length > 0 &&
118
156
  utils_1.t.isObjectExpression(args[0].expression)) {
119
157
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
@@ -131,6 +169,8 @@ async function loader(source) {
131
169
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
132
170
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
133
171
  utils_1.tables.viewTransitionObjectTable[hash] = obj;
172
+ (0, utils_1.extractOndemandStyles)(obj, extractedSheets);
173
+ (0, utils_1.extractOndemandStyles)({ vt: `vt-${hash}` }, extractedSheets);
134
174
  replacements.push({
135
175
  start: node.span.start - ast.span.start,
136
176
  end: node.span.end - ast.span.start,
@@ -143,37 +183,202 @@ async function loader(source) {
143
183
  const obj = (0, utils_1.objectExpressionToObject)(args[0].expression, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
144
184
  const hash = (0, zss_engine_1.genBase36Hash)(obj, 1, 8);
145
185
  utils_1.tables.createThemeObjectTable[hash] = obj;
146
- replacements.push({
147
- start: node.span.start - ast.span.start,
148
- end: node.span.end - ast.span.start,
149
- content: JSON.stringify(''),
150
- });
151
186
  }
152
- else if (callee.property.value === 'createStatic' &&
153
- args.length > 0 &&
154
- utils_1.t.isStringLiteral(args[0].expression)) {
155
- replacements.push({
156
- start: node.span.start - ast.span.start,
157
- end: node.span.end - ast.span.start,
158
- content: JSON.stringify(''),
187
+ }
188
+ },
189
+ });
190
+ (0, utils_1.traverse)(ast, {
191
+ MemberExpression({ node }) {
192
+ if (excludedSpans.has(node.span.start))
193
+ return;
194
+ if (utils_1.t.isIdentifier(node.object) && utils_1.t.isIdentifier(node.property)) {
195
+ const styleInfo = localCreateStyles[node.object.value];
196
+ if (styleInfo && !styleInfo.hasDynamicAccess) {
197
+ const atomMap = styleInfo.hashMap[node.property.value];
198
+ if (atomMap) {
199
+ const combinedHash = Object.values(atomMap).join(' ');
200
+ replacements.push({
201
+ start: node.span.start - ast.span.start,
202
+ end: node.span.end - ast.span.start,
203
+ content: JSON.stringify(combinedHash),
204
+ });
205
+ }
206
+ }
207
+ }
208
+ },
209
+ Identifier({ node }) {
210
+ if (excludedSpans.has(node.span.start))
211
+ return;
212
+ if (idSpans.has(node.span.start))
213
+ return;
214
+ const styleInfo = localCreateStyles[node.value];
215
+ if (styleInfo && !styleInfo.hasDynamicAccess) {
216
+ const fullHashMap = {};
217
+ Object.entries(styleInfo.hashMap).forEach(([key, atomMap]) => {
218
+ fullHashMap[key] = Object.values(atomMap).join(' ');
219
+ });
220
+ replacements.push({
221
+ start: node.span.start - ast.span.start,
222
+ end: node.span.end - ast.span.start,
223
+ content: JSON.stringify(fullHashMap),
224
+ });
225
+ }
226
+ },
227
+ CallExpression({ node }) {
228
+ const callee = node.callee;
229
+ if (utils_1.t.isMemberExpression(callee) &&
230
+ utils_1.t.isIdentifier(callee.object, { name: 'css' }) &&
231
+ utils_1.t.isIdentifier(callee.property, { name: 'props' })) {
232
+ const args = node.arguments;
233
+ const checkStatic = (expr) => {
234
+ if (utils_1.t.isObjectExpression(expr) ||
235
+ utils_1.t.isStringLiteral(expr) ||
236
+ utils_1.t.isNumericLiteral(expr) ||
237
+ utils_1.t.isBooleanLiteral(expr) ||
238
+ utils_1.t.isNullLiteral(expr))
239
+ return true;
240
+ if (utils_1.t.isMemberExpression(expr) &&
241
+ utils_1.t.isIdentifier(expr.object) &&
242
+ utils_1.t.isIdentifier(expr.property)) {
243
+ const styleInfo = localCreateStyles[expr.object.value];
244
+ return !!(styleInfo &&
245
+ !styleInfo.hasDynamicAccess &&
246
+ styleInfo.hashMap[expr.property.value]);
247
+ }
248
+ if (utils_1.t.isIdentifier(expr)) {
249
+ const styleInfo = localCreateStyles[expr.value];
250
+ return !!(styleInfo && !styleInfo.hasDynamicAccess);
251
+ }
252
+ return false;
253
+ };
254
+ const allStatic = args.every((arg) => checkStatic(arg.expression));
255
+ if (allStatic) {
256
+ const merged = {};
257
+ args.forEach((arg) => {
258
+ const expr = arg.expression;
259
+ if (utils_1.t.isObjectExpression(expr)) {
260
+ const obj = (0, utils_1.objectExpressionToObject)(expr, utils_1.tables.staticTable, utils_1.tables.keyframesHashTable, utils_1.tables.viewTransitionHashTable, utils_1.tables.themeTable);
261
+ obj && Object.assign(merged, obj);
262
+ }
263
+ else if (utils_1.t.isMemberExpression(expr) &&
264
+ utils_1.t.isIdentifier(expr.object) &&
265
+ utils_1.t.isIdentifier(expr.property)) {
266
+ const styleInfo = localCreateStyles[expr.object.value];
267
+ if (styleInfo) {
268
+ Object.assign(merged, styleInfo.obj[expr.property.value]);
269
+ }
270
+ }
271
+ else if (utils_1.t.isIdentifier(expr)) {
272
+ const styleInfo = localCreateStyles[expr.value];
273
+ if (styleInfo) {
274
+ Object.assign(merged, styleInfo.obj);
275
+ }
276
+ }
159
277
  });
278
+ if (Object.keys(merged).length > 0) {
279
+ (0, utils_1.extractOndemandStyles)(merged, extractedSheets);
280
+ const hash = (0, zss_engine_1.genBase36Hash)(merged, 1, 8);
281
+ const records = (0, utils_1.getStyleRecords)(hash, merged, 2);
282
+ records.forEach((r) => extractedSheets.push(r.sheet));
283
+ const resultHash = records
284
+ .map((r) => r.hash)
285
+ .join(' ');
286
+ replacements.push({
287
+ start: node.span.start - ast.span.start,
288
+ end: node.span.end - ast.span.start,
289
+ content: JSON.stringify(resultHash),
290
+ });
291
+ }
292
+ }
293
+ else {
294
+ const processExpr = (expr) => {
295
+ if (utils_1.t.isMemberExpression(expr) &&
296
+ utils_1.t.isIdentifier(expr.object) &&
297
+ utils_1.t.isIdentifier(expr.property)) {
298
+ const info = localCreateStyles[expr.object.value];
299
+ if (info) {
300
+ const atomMap = info.hashMap[expr.property.value];
301
+ if (atomMap) {
302
+ excludedSpans.add(expr.span.start);
303
+ replacements.push({
304
+ start: expr.span.start - ast.span.start,
305
+ end: expr.span.end - ast.span.start,
306
+ content: JSON.stringify(atomMap),
307
+ });
308
+ }
309
+ }
310
+ }
311
+ else if (utils_1.t.isIdentifier(expr)) {
312
+ const info = localCreateStyles[expr.value];
313
+ if (info) {
314
+ info.hasDynamicAccess = true;
315
+ excludedSpans.add(expr.span.start);
316
+ replacements.push({
317
+ start: expr.span.start - ast.span.start,
318
+ end: expr.span.end - ast.span.start,
319
+ content: JSON.stringify(info.hashMap),
320
+ });
321
+ }
322
+ }
323
+ else if (utils_1.t.isConditionalExpression(expr)) {
324
+ processExpr(expr.consequent);
325
+ processExpr(expr.alternate);
326
+ }
327
+ else if (utils_1.t.isBinaryExpression(expr) &&
328
+ (expr.operator === '&&' ||
329
+ expr.operator === '||' ||
330
+ expr.operator === '??')) {
331
+ processExpr(expr.left);
332
+ processExpr(expr.right);
333
+ }
334
+ };
335
+ args.forEach((arg) => processExpr(arg.expression));
160
336
  }
161
337
  }
162
338
  },
163
339
  });
340
+ Object.values(localCreateStyles).forEach((info) => {
341
+ if (info.isExported) {
342
+ const content = isTSFile || info.hasDynamicAccess
343
+ ? JSON.stringify(info.hashMap)
344
+ : JSON.stringify('');
345
+ replacements.push({
346
+ start: info.initSpan.start,
347
+ end: info.initSpan.end,
348
+ content,
349
+ });
350
+ }
351
+ else {
352
+ if (info.hasDynamicAccess) {
353
+ replacements.push({
354
+ start: info.initSpan.start,
355
+ end: info.initSpan.end,
356
+ content: JSON.stringify(info.hashMap),
357
+ });
358
+ }
359
+ else {
360
+ replacements.push({
361
+ start: info.declSpan.start,
362
+ end: info.declSpan.end,
363
+ content: '',
364
+ });
365
+ }
366
+ }
367
+ });
164
368
  const buffer = Buffer.from(source);
165
369
  let offset = 0;
166
370
  const parts = [];
167
371
  replacements
168
- .sort((a, b) => a.start - b.start)
372
+ .sort((a, b) => a.start - b.start || b.end - a.end)
169
373
  .forEach((r) => {
374
+ if (r.start < offset)
375
+ return;
170
376
  parts.push(buffer.subarray(offset, r.start));
171
377
  parts.push(Buffer.from(r.content));
172
378
  offset = r.end;
173
379
  });
174
380
  parts.push(buffer.subarray(offset));
175
381
  const transformedSource = Buffer.concat(parts).toString();
176
- const VIRTUAL_FILE_PATH = path_1.default.resolve(__dirname, '..', 'zero-virtual.css');
177
382
  const VIRTUAL_CSS_PATH = require.resolve(VIRTUAL_FILE_PATH);
178
383
  function stringifyRequest(loaderContext, request) {
179
384
  const context = loaderContext.context || loaderContext.rootContext;
@@ -190,14 +395,10 @@ async function loader(source) {
190
395
  }
191
396
  const virtualCssRequest = stringifyRequest(this, `${VIRTUAL_CSS_PATH}`);
192
397
  const postfix = `\nimport ${virtualCssRequest};`;
398
+ if (process.env.NODE_ENV === 'production')
399
+ return callback(null, transformedSource);
193
400
  if (extractedSheets.length > 0 && process.env.NODE_ENV === 'development') {
194
401
  fs_1.default.appendFileSync(VIRTUAL_FILE_PATH, extractedSheets.join(''), 'utf-8');
195
402
  }
196
- else if (extractedSheets.length > 0 &&
197
- process.env.NODE_ENV === 'production') {
198
- fs_1.default.writeFileSync(VIRTUAL_FILE_PATH, '');
199
- }
200
- if (process.env.NODE_ENV === 'production')
201
- return callback(null, transformedSource);
202
- callback(null, transformedSource + postfix);
403
+ return callback(null, transformedSource + postfix);
203
404
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/turbopack-loader",
3
- "version": "3.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Plumeria Turbopack-loader",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  "zero-virtual.css"
23
23
  ],
24
24
  "dependencies": {
25
- "@plumeria/utils": "^3.0.1"
25
+ "@plumeria/utils": "^4.0.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@swc/core": "1.15.2",