@camstack/addon-sample 0.1.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.
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/sample.addon.ts
21
+ var sample_addon_exports = {};
22
+ __export(sample_addon_exports, {
23
+ default: () => SampleWorkerAddon
24
+ });
25
+ module.exports = __toCommonJS(sample_addon_exports);
26
+ var SampleWorkerAddon = class _SampleWorkerAddon {
27
+ static manifest = {
28
+ id: "sample-worker",
29
+ name: "Sample Worker",
30
+ description: "Demo addon that runs in a forked process and spawns sub-processes",
31
+ version: "0.1.0"
32
+ };
33
+ manifest = _SampleWorkerAddon.manifest;
34
+ context;
35
+ subProcesses = [];
36
+ monitorInterval = null;
37
+ spawnInterval = null;
38
+ async initialize(context) {
39
+ this.context = context;
40
+ const { logger } = context;
41
+ logger.info("SampleWorkerAddon initializing \u2014 spawning initial sub-processes");
42
+ for (let i = 0; i < 3; i++) {
43
+ await this.spawnRandomProcess(i);
44
+ }
45
+ this.monitorInterval = setInterval(() => {
46
+ const alive = this.subProcesses.filter((p) => {
47
+ try {
48
+ return p.getStats().state === "running";
49
+ } catch {
50
+ return false;
51
+ }
52
+ });
53
+ logger.info(`[sample-worker] Active sub-processes: ${alive.length}/${this.subProcesses.length}`);
54
+ }, 5e3);
55
+ this.spawnInterval = setInterval(async () => {
56
+ const idx = this.subProcesses.length;
57
+ logger.info(`[sample-worker] Spawning new random process #${idx}`);
58
+ await this.spawnRandomProcess(idx);
59
+ }, 1e4 + Math.random() * 1e4);
60
+ logger.info("SampleWorkerAddon initialized \u2014 monitoring sub-processes");
61
+ }
62
+ async spawnRandomProcess(index) {
63
+ if (!this.context.process) {
64
+ this.context.logger.warn("No process manager available \u2014 cannot spawn");
65
+ return;
66
+ }
67
+ const durationSec = 5 + Math.floor(Math.random() * 25);
68
+ const proc = await this.context.process.spawn({
69
+ name: `sample-child-${index}`,
70
+ command: "node",
71
+ args: ["-e", `
72
+ const duration = ${durationSec * 1e3};
73
+ const start = Date.now();
74
+ console.log('Child ${index} started, will run for ${durationSec}s');
75
+ const interval = setInterval(() => {
76
+ const elapsed = Math.round((Date.now() - start) / 1000);
77
+ // Simulate some CPU work
78
+ let sum = 0;
79
+ for (let i = 0; i < 100000; i++) sum += Math.sqrt(i);
80
+ }, 2000);
81
+ setTimeout(() => {
82
+ clearInterval(interval);
83
+ console.log('Child ${index} exiting normally');
84
+ process.exit(0);
85
+ }, duration);
86
+ `],
87
+ autoRestart: false
88
+ });
89
+ this.subProcesses.push(proc);
90
+ this.context.logger.info(`[sample-worker] Spawned child-${index} (PID ${proc.pid}, duration ${durationSec}s)`);
91
+ proc.onExit((code) => {
92
+ this.context.logger.info(`[sample-worker] child-${index} (PID ${proc.pid}) exited with code ${code}`);
93
+ });
94
+ }
95
+ async shutdown() {
96
+ if (this.monitorInterval) clearInterval(this.monitorInterval);
97
+ if (this.spawnInterval) clearInterval(this.spawnInterval);
98
+ for (const proc of this.subProcesses) {
99
+ try {
100
+ proc.kill();
101
+ } catch {
102
+ }
103
+ }
104
+ this.context.logger.info("SampleWorkerAddon shut down \u2014 all sub-processes killed");
105
+ }
106
+ };
107
+ //# sourceMappingURL=sample.addon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sample.addon.ts"],"sourcesContent":["import type { ICamstackAddon, AddonContext, IManagedSubProcess } from '@camstack/types'\n\nexport default class SampleWorkerAddon implements ICamstackAddon {\n static readonly manifest = {\n id: 'sample-worker',\n name: 'Sample Worker',\n description: 'Demo addon that runs in a forked process and spawns sub-processes',\n version: '0.1.0',\n }\n\n readonly manifest = SampleWorkerAddon.manifest\n\n private context!: AddonContext\n private readonly subProcesses: IManagedSubProcess[] = []\n private monitorInterval: ReturnType<typeof setInterval> | null = null\n private spawnInterval: ReturnType<typeof setInterval> | null = null\n\n async initialize(context: AddonContext): Promise<void> {\n this.context = context\n const { logger } = context\n\n logger.info('SampleWorkerAddon initializing — spawning initial sub-processes')\n\n // Spawn 3 initial sub-processes\n for (let i = 0; i < 3; i++) {\n await this.spawnRandomProcess(i)\n }\n\n // Monitor: every 5s, log process status\n this.monitorInterval = setInterval(() => {\n const alive = this.subProcesses.filter(p => {\n try { return p.getStats().state === 'running' } catch { return false }\n })\n logger.info(`[sample-worker] Active sub-processes: ${alive.length}/${this.subProcesses.length}`)\n }, 5000)\n\n // Randomly spawn new processes every 10-20s\n this.spawnInterval = setInterval(async () => {\n const idx = this.subProcesses.length\n logger.info(`[sample-worker] Spawning new random process #${idx}`)\n await this.spawnRandomProcess(idx)\n }, 10000 + Math.random() * 10000)\n\n logger.info('SampleWorkerAddon initialized — monitoring sub-processes')\n }\n\n private async spawnRandomProcess(index: number): Promise<void> {\n if (!this.context.process) {\n this.context.logger.warn('No process manager available — cannot spawn')\n return\n }\n\n const durationSec = 5 + Math.floor(Math.random() * 25) // 5-30 seconds\n\n const proc = await this.context.process.spawn({\n name: `sample-child-${index}`,\n command: 'node',\n args: ['-e', `\n const duration = ${durationSec * 1000};\n const start = Date.now();\n console.log('Child ${index} started, will run for ${durationSec}s');\n const interval = setInterval(() => {\n const elapsed = Math.round((Date.now() - start) / 1000);\n // Simulate some CPU work\n let sum = 0;\n for (let i = 0; i < 100000; i++) sum += Math.sqrt(i);\n }, 2000);\n setTimeout(() => {\n clearInterval(interval);\n console.log('Child ${index} exiting normally');\n process.exit(0);\n }, duration);\n `],\n autoRestart: false,\n })\n\n this.subProcesses.push(proc)\n this.context.logger.info(`[sample-worker] Spawned child-${index} (PID ${proc.pid}, duration ${durationSec}s)`)\n\n proc.onExit((code) => {\n this.context.logger.info(`[sample-worker] child-${index} (PID ${proc.pid}) exited with code ${code}`)\n })\n }\n\n async shutdown(): Promise<void> {\n if (this.monitorInterval) clearInterval(this.monitorInterval)\n if (this.spawnInterval) clearInterval(this.spawnInterval)\n\n for (const proc of this.subProcesses) {\n try { proc.kill() } catch { /* already dead */ }\n }\n\n this.context.logger.info('SampleWorkerAddon shut down — all sub-processes killed')\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAqB,oBAArB,MAAqB,mBAA4C;AAAA,EAC/D,OAAgB,WAAW;AAAA,IACzB,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,IACb,SAAS;AAAA,EACX;AAAA,EAES,WAAW,mBAAkB;AAAA,EAE9B;AAAA,EACS,eAAqC,CAAC;AAAA,EAC/C,kBAAyD;AAAA,EACzD,gBAAuD;AAAA,EAE/D,MAAM,WAAW,SAAsC;AACrD,SAAK,UAAU;AACf,UAAM,EAAE,OAAO,IAAI;AAEnB,WAAO,KAAK,sEAAiE;AAG7E,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,KAAK,mBAAmB,CAAC;AAAA,IACjC;AAGA,SAAK,kBAAkB,YAAY,MAAM;AACvC,YAAM,QAAQ,KAAK,aAAa,OAAO,OAAK;AAC1C,YAAI;AAAE,iBAAO,EAAE,SAAS,EAAE,UAAU;AAAA,QAAU,QAAQ;AAAE,iBAAO;AAAA,QAAM;AAAA,MACvE,CAAC;AACD,aAAO,KAAK,yCAAyC,MAAM,MAAM,IAAI,KAAK,aAAa,MAAM,EAAE;AAAA,IACjG,GAAG,GAAI;AAGP,SAAK,gBAAgB,YAAY,YAAY;AAC3C,YAAM,MAAM,KAAK,aAAa;AAC9B,aAAO,KAAK,gDAAgD,GAAG,EAAE;AACjE,YAAM,KAAK,mBAAmB,GAAG;AAAA,IACnC,GAAG,MAAQ,KAAK,OAAO,IAAI,GAAK;AAEhC,WAAO,KAAK,+DAA0D;AAAA,EACxE;AAAA,EAEA,MAAc,mBAAmB,OAA8B;AAC7D,QAAI,CAAC,KAAK,QAAQ,SAAS;AACzB,WAAK,QAAQ,OAAO,KAAK,kDAA6C;AACtE;AAAA,IACF;AAEA,UAAM,cAAc,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE;AAErD,UAAM,OAAO,MAAM,KAAK,QAAQ,QAAQ,MAAM;AAAA,MAC5C,MAAM,gBAAgB,KAAK;AAAA,MAC3B,SAAS;AAAA,MACT,MAAM,CAAC,MAAM;AAAA,2BACQ,cAAc,GAAI;AAAA;AAAA,6BAEhB,KAAK,0BAA0B,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+BASxC,KAAK;AAAA;AAAA;AAAA,OAG7B;AAAA,MACD,aAAa;AAAA,IACf,CAAC;AAED,SAAK,aAAa,KAAK,IAAI;AAC3B,SAAK,QAAQ,OAAO,KAAK,iCAAiC,KAAK,SAAS,KAAK,GAAG,cAAc,WAAW,IAAI;AAE7G,SAAK,OAAO,CAAC,SAAS;AACpB,WAAK,QAAQ,OAAO,KAAK,yBAAyB,KAAK,SAAS,KAAK,GAAG,sBAAsB,IAAI,EAAE;AAAA,IACtG,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAA0B;AAC9B,QAAI,KAAK,gBAAiB,eAAc,KAAK,eAAe;AAC5D,QAAI,KAAK,cAAe,eAAc,KAAK,aAAa;AAExD,eAAW,QAAQ,KAAK,cAAc;AACpC,UAAI;AAAE,aAAK,KAAK;AAAA,MAAE,QAAQ;AAAA,MAAqB;AAAA,IACjD;AAEA,SAAK,QAAQ,OAAO,KAAK,6DAAwD;AAAA,EACnF;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@camstack/addon-sample",
3
+ "version": "0.1.1",
4
+ "description": "Demo addon that runs in a forked worker process and spawns sub-processes",
5
+ "main": "./dist/sample.addon.js",
6
+ "camstack": {
7
+ "addons": [
8
+ {
9
+ "id": "sample-worker",
10
+ "entry": "./dist/sample.addon.js",
11
+ "slot": "utility",
12
+ "forkable": true,
13
+ "capabilities": []
14
+ }
15
+ ]
16
+ },
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "dev": "tsup --watch",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "devDependencies": {
23
+ "@camstack/types": "*",
24
+ "tsup": "^8.5.1",
25
+ "typescript": "^5.7.0"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ]
30
+ }