todos-contra-el-fuego-web/imports/startup/server/calcUnionAsync.js
vjrj 4879d3482d
Some checks failed
build-image / build (push) Has been cancelled
fix(subsUnion): force-bundle turf deps used only by the worker thread
Meteor's build only includes npm packages it sees imported/required
somewhere in its own traced module graph. private/workers/unionWorker.js
is a plain asset (loaded at runtime via new Worker(), never
import/require'd from Meteor-compiled code), so @turf/circle,
@turf/union and @turf/truncate got silently dropped from
programs/server/node_modules — the worker crashed on every call with
"Cannot find module '@turf/circle'", which incrementalAdd/process
swallowed and stored as a "null" union (typeof null === 'object', so
the null-check that guards against failed unions doesn't catch it).
Side-effect imports here force Meteor to bundle them.
2026-07-30 08:27:40 +02:00

39 lines
1.5 KiB
JavaScript

import path from 'path';
import { Worker } from 'worker_threads';
// Meteor only bundles the npm packages it sees imported/required somewhere in
// its own compiled module graph. The actual usage of these three is inside
// private/workers/unionWorker.js, a plain asset file Meteor's bundler never
// traces (it's loaded at runtime via new Worker(), not import/require here).
// Without this, `meteor build` drops them from programs/server/node_modules
// and the worker fails at startup with "Cannot find module '@turf/circle'".
import '@turf/circle';
import '@turf/union';
import '@turf/truncate';
const WORKER_PATH = path.resolve(process.cwd(), 'assets/app/workers/unionWorker.js');
/**
* Circle-union of already-validated, already-decorated subscriptions, run in a
* worker thread so the main event loop (DDP/HTTP) stays free regardless of
* how long any single turf.union call takes. subs must be an array of plain
* { location: { lat, lon }, distance } objects. If baseUnion is given, subs
* are merged into it instead of a union computed from scratch.
*/
const calcUnionAsync = (subs, baseUnion = null) => new Promise((resolve, reject) => {
const worker = new Worker(WORKER_PATH, { workerData: { subs, baseUnion } });
worker.once('message', (msg) => {
worker.terminate();
if (msg.error) {
reject(new Error(msg.error));
} else {
resolve(msg.union);
}
});
worker.once('error', (err) => {
worker.terminate();
reject(err);
});
});
export default calcUnionAsync;