@dimina-kit/compiler 0.0.1 → 0.0.2-dev.20260711062001

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 (27) hide show
  1. package/README.md +8 -3
  2. package/dist/compile-core.browser.js +1331 -1252
  3. package/dist/{pool.node-chunks/chunk-FVCSERCO.js → compile-core.node-chunks/chunk-LUD2P6RM.js} +5 -1
  4. package/dist/compile-core.node-chunks/{chunk-5ND5V2SC.js → chunk-QJ34C5KK.js} +77 -2
  5. package/dist/compile-core.node-chunks/{logic-compiler-RX63Y2FZ.js → logic-compiler-2SQFOFEO.js} +2 -2
  6. package/dist/compile-core.node-chunks/{style-compiler-JUY5MZSO.js → style-compiler-ZEJ3XLTS.js} +3 -3
  7. package/dist/compile-core.node-chunks/{view-compiler-KA2OZG44.js → view-compiler-WQNV7H5G.js} +25 -23
  8. package/dist/compile-core.node.js +10 -7
  9. package/dist/pool.browser.js +6 -5
  10. package/dist/pool.node-chunks/{chunk-UYQ7D5I5.js → chunk-7FGOYOXU.js} +77 -2
  11. package/dist/{compile-core.node-chunks/chunk-CCZB2BJG.js → pool.node-chunks/chunk-C7GEIDCP.js} +5 -1
  12. package/dist/pool.node-chunks/{chunk-MHOA4NGC.js → chunk-PDHO4Y56.js} +8 -5
  13. package/dist/pool.node-chunks/{logic-compiler-3VVLN3YN.js → logic-compiler-BODAINZQ.js} +2 -2
  14. package/dist/pool.node-chunks/{style-compiler-QOUWS72U.js → style-compiler-TUNDVSR5.js} +3 -3
  15. package/dist/pool.node-chunks/{view-compiler-KAYOMOXO.js → view-compiler-HOFFL63K.js} +25 -23
  16. package/dist/pool.node.js +34 -11
  17. package/dist/stage-worker.browser.js +1337 -1258
  18. package/dist/stage-worker.node.js +2 -2
  19. package/package.json +4 -2
  20. package/scripts/test-pool-filetypes.js +159 -0
  21. package/scripts/test-pool-node.js +93 -3
  22. package/scripts/test-pool-toolchain-death.js +135 -0
  23. package/scripts/toolchain-setup-node-native.js +13 -0
  24. package/src/compile-core.js +8 -5
  25. package/src/pool-node.js +84 -17
  26. package/src/pool.js +23 -10
  27. package/src/stage-worker.js +12 -8
package/src/pool.js CHANGED
@@ -159,10 +159,10 @@ export function createCompilerPool(options = {}) {
159
159
  // One full compile attempt against the resident realms. Ends quiescent: settleAll
160
160
  // guarantees no request is still in flight when it returns/throws, so a retry can
161
161
  // start fresh without cross-attempt FIFO pairing.
162
- async function runAttempt(files, workPath) {
162
+ async function runAttempt(files, workPath, options) {
163
163
  await settleAll(workers.map(ensureWarm))
164
164
 
165
- // Phase 1 — one worker runs setup ONCE: it allocates the scope-hash ids
165
+ // Setup step — one worker runs setup ONCE: it allocates the scope-hash ids
166
166
  // (page + component data-v-XXXXX) and builds miniprogram_npm/app-config.json.
167
167
  // Broadcasting this single bundle to every stage is REQUIRED for correctness:
168
168
  // each stage runs in its own realm, and if each ran its own setup it would roll
@@ -170,10 +170,15 @@ export function createCompilerPool(options = {}) {
170
170
  // the render `Module id` and every WXSS rule would target nothing (regression
171
171
  // guarded by scripts/test-pool-scopehash.js). This mirrors the Node disk pool,
172
172
  // which likewise sets up once and fans the same { pages, storeInfo } out.
173
- const s = await requestChecked(workers[0], { type: 'setup', files, workPath, wantHeartbeat: true }, 'setup', sendTimeoutMs)
173
+ // `options` (e.g. { fileTypes }) only needs to reach THIS setup call: dmcc's
174
+ // storeInfo() bakes the normalized dialect into the returned storeInfo object
175
+ // (dimina/fe/packages/compiler/src/env.js:106-120), which rides inside `bundle`
176
+ // below and is restored per-stage via resetStoreInfo (compile-core.js's
177
+ // compileStage -> env.js:122-132) — so compile-subset never needs its own copy.
178
+ const s = await requestChecked(workers[0], { type: 'setup', files, workPath, options, wantHeartbeat: true }, 'setup', sendTimeoutMs)
174
179
  const { bundle, scaffold } = s
175
180
 
176
- // Phase 2 — every stage compiles in parallel against the SHARED bundle. The
181
+ // Compile step — every stage compiles in parallel against the SHARED bundle. The
177
182
  // non-stage scaffold (app-config.json + npm, produced once) seeds the union.
178
183
  const parts = await settleAll(workers.map((x) =>
179
184
  requestChecked(x, { type: 'compile-subset', files, workPath, stages: [x.stage], bundle, wantHeartbeat: true }, 'compile-subset', sendTimeoutMs)))
@@ -188,9 +193,16 @@ export function createCompilerPool(options = {}) {
188
193
  let chain = Promise.resolve()
189
194
 
190
195
  /**
191
- * Single argument, no ambiguity: pass { files, workPath }. A bare { relPath: content }
192
- * map is also accepted (uses the default workPath).
193
- * @param {{ files: Record<string,string>, workPath?: string } | Record<string,string>} input
196
+ * Single argument, no ambiguity: pass { files, workPath, options }. A bare
197
+ * { relPath: content } map is also accepted (uses the default workPath, no options).
198
+ * @param {{
199
+ * files: Record<string,string>,
200
+ * workPath?: string,
201
+ * options?: { fileTypes?: { template?: string[], style?: string[], viewScript?: string[] } },
202
+ * } | Record<string,string>} input
203
+ * options.fileTypes lets a caller register a custom template/style/view-script
204
+ * dialect (e.g. { template: ['qdml'], style: ['qdss'], viewScript: ['qds'] }) —
205
+ * forwarded to the setup worker's `setupCompile` (dmcc's storeInfo).
194
206
  * @returns {Promise<{ appId: string, name: string, files: Record<string,string> }>}
195
207
  */
196
208
  function compile(input = {}) {
@@ -200,17 +212,18 @@ export function createCompilerPool(options = {}) {
200
212
  }
201
213
  const files = input.files || input
202
214
  if (!files || typeof files !== 'object' || !Object.keys(files).length) {
203
- throw new Error('[compiler] pool.compile expects { files: { relPath: content }, workPath? } (or a non-empty files map)')
215
+ throw new Error('[compiler] pool.compile expects { files: { relPath: content }, workPath?, options? } (or a non-empty files map)')
204
216
  }
205
217
  const workPath = input.workPath || defaultWorkPath
218
+ const options = input.options || {}
206
219
  try {
207
- return await runAttempt(files, workPath)
220
+ return await runAttempt(files, workPath, options)
208
221
  } catch (err) {
209
222
  // A worker death is often transient (memory pressure, tab freeze, a one-off
210
223
  // toolchain stall) — retry the WHOLE attempt once on fresh workers. Real
211
224
  // compile errors (bad user source) are deterministic and are never retried.
212
225
  if (!retryOnWorkerDeath || !err || !WORKER_DEATH_CODES.has(err.code)) throw err
213
- return await runAttempt(files, workPath)
226
+ return await runAttempt(files, workPath, options)
214
227
  }
215
228
  })
216
229
  // keep the chain alive regardless of this compile's outcome
@@ -65,10 +65,10 @@ function freshFs(files, workPath) {
65
65
  // what keeps the CSS `[data-v-X]` selectors and the render `Module id` in agreement:
66
66
  // if each stage ran its own setupCompile it would roll its own random uuids and every
67
67
  // WXSS rule would target a selector that never renders (see scripts/test-pool-scopehash.js).
68
- async function runSetup(files, workPath) {
68
+ async function runSetup(files, workPath, options) {
69
69
  const fs = freshFs(files, workPath)
70
70
  resetCompilerState()
71
- const ctx = await setupCompile({ fs, workPath })
71
+ const ctx = await setupCompile({ fs, workPath, options })
72
72
  const map = collectOutputs({ fs, targetPath: ctx.targetPath })
73
73
  const scaffold = {}
74
74
  for (const k of Object.keys(map)) if (map[k] != null) scaffold[k] = map[k]
@@ -93,7 +93,11 @@ async function runSetup(files, workPath) {
93
93
  // cross-stage scope-hash mismatch. Stages read source from `workPath` and write
94
94
  // disjoint products; they never read the setup scaffold, so it is not seeded here.
95
95
  // Without a bundle the worker stays self-contained (single-worker / legacy callers).
96
- async function compileSubset(files, workPath, stages, bundle) {
96
+ // `options` (e.g. { fileTypes }) is only used on the no-bundle fallback path: with a
97
+ // bundle, its storeInfo already carries the normalized dialect from the coordinator's
98
+ // setupCompile call (see runSetup below / pool.js's runAttempt), restored via
99
+ // compileStage -> resetStoreInfo, so re-deriving it here would be redundant.
100
+ async function compileSubset(files, workPath, stages, bundle, options) {
97
101
  const fs = freshFs(files, workPath)
98
102
  resetCompilerState()
99
103
  let appId, name, targetPath
@@ -103,7 +107,7 @@ async function compileSubset(files, workPath, stages, bundle) {
103
107
  }
104
108
  ;({ appId, name, targetPath } = bundle)
105
109
  } else {
106
- const ctx = await setupCompile({ fs, workPath })
110
+ const ctx = await setupCompile({ fs, workPath, options })
107
111
  for (const stage of stages) {
108
112
  await compileStage({ stage, pages: ctx.pages, storeInfo: ctx.storeInfo, fs })
109
113
  }
@@ -150,21 +154,21 @@ self.onmessage = async (e) => {
150
154
  // Coordinator phase: one worker parses config, allocates the shared scope-hash
151
155
  // ids and builds miniprogram_npm once. setupCompile's npm build can invoke the
152
156
  // wasm toolchain, so ensure it's loaded regardless of this worker's own stage.
153
- const { files, workPath = '/work', toolchainSetupURL } = e.data
157
+ const { files, workPath = '/work', options, toolchainSetupURL } = e.data
154
158
  if (toolchainSetupURL) toolchainURL = toolchainSetupURL
155
159
  await ensureToolchain()
156
160
  const t = performance.now()
157
- const { bundle, scaffold } = await runSetup(files, workPath)
161
+ const { bundle, scaffold } = await runSetup(files, workPath, options)
158
162
  self.postMessage({ type: 'setup-done', bundle, scaffold, ms: Math.round(performance.now() - t) })
159
163
  return
160
164
  }
161
165
  if (type === 'compile-subset') {
162
- const { files, workPath = '/work', stages = ['logic', 'view', 'style'], bundle, toolchainSetupURL } = e.data
166
+ const { files, workPath = '/work', stages = ['logic', 'view', 'style'], bundle, options, toolchainSetupURL } = e.data
163
167
  if (toolchainSetupURL) toolchainURL = toolchainSetupURL
164
168
  if (needsToolchain(stages)) await ensureToolchain()
165
169
  const warm = !!toolchainReady
166
170
  const t = performance.now()
167
- const result = await compileSubset(files, workPath, stages, bundle)
171
+ const result = await compileSubset(files, workPath, stages, bundle, options)
168
172
  self.postMessage({ type: 'done', result, ms: Math.round(performance.now() - t), warm })
169
173
  return
170
174
  }