{"_id":"@artpar/workflow-engine-service-worker","_rev":"3-c23aece6a667e7ea6f9fc870f993efc8","name":"@artpar/workflow-engine-service-worker","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@artpar/workflow-engine-service-worker","version":"1.0.0","keywords":["service-worker","chrome-extension","browser","workflow","engine","jsonata","json-template","transformation","rudder","rudderstack"],"author":{"name":"RudderStack"},"license":"MIT","_id":"@artpar/workflow-engine-service-worker@1.0.0","maintainers":[{"name":"artpar","email":"artpar@gmail.com"}],"homepage":"https://github.com/rudderlabs/rudder-workflow-engine#readme","bugs":{"url":"https://github.com/rudderlabs/rudder-workflow-engine/issues"},"dist":{"shasum":"51c3e414d298488275b7729defdf33346b6fed4a","tarball":"https://registry.npmjs.org/@artpar/workflow-engine-service-worker/-/workflow-engine-service-worker-1.0.0.tgz","fileCount":136,"integrity":"sha512-ZIRW3K0qr+dD5AFZ7WqgdpmiZO4KjlAhYvGqHBhQbm+LxlMxn8njoE0vey9Jpd1Jd7opuCJKc7E/sLBYjmjPAQ==","signatures":[{"sig":"MEQCIHRVa4KCmO6ooCzk3eysdh8KwwFRgcLWUlfJXvd2Gq7fAiB4gwGGCaeFx8joHcnwDBR3qkLI5vExFujr3Pf4nQg1+g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":181256},"main":"build/index.js","types":"build/index.d.ts","exports":{".":{"types":"./build/index.d.ts","import":"./build/index.js","require":"./build/index.js"},"./service-worker":{"types":"./build/service-worker/index.d.ts","import":"./build/service-worker/index.js","require":"./build/service-worker/index.js"}},"gitHead":"7ccd193be19b4caa33adebd8f210926e0f89b948","scripts":{"lint":"npm run format && npm run lint:fix","test":"jest --coverage --verbose","build":"tsc --project tsconfig.build.json","clean":"rm -rf build","format":"prettier --write '**/*.ts' '**/*.json'","prepare":"husky install","lint:fix":"eslint . --fix","check:lint":"eslint . -f json -o reports/eslint.json || exit 0","lint:check":"eslint . || exit 1","build:clean":"npm run clean && npm run build","lint-staged":"lint-staged","test:stryker":"stryker run","test:scenario":"jest test/scenario.test.ts --verbose","jest:scenarios":"jest e2e.test.ts --verbose","test:no-logging":"LOG_LEVEL=100 jest --coverage --verbose"},"_npmUser":{"name":"artpar","email":"artpar@gmail.com"},"repository":{"url":"git+https://github.com/rudderlabs/rudder-workflow-engine.git","type":"git"},"_npmVersion":"10.9.2","description":"Service Worker workflow execution engine - Run complex data transformations in Chrome service workers and browser extensions","directories":{},"lint-staged":{"*.(ts|json|yaml)":"prettier --write"},"_nodeVersion":"22.17.0","dependencies":{"yaml":"^2.6.0","lodash":"^4.17.21","jsonata":"^2.0.5","object-sizeof":"^2.6.5","@aws-crypto/sha256-js":"^5.2.0","@rudderstack/json-template-engine":"^0.19.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.4.3","husky":"^8.0.3","eslint":"^8.35.0","ts-jest":"^29.0.5","ts-node":"^10.9.1","prettier":"^2.8.4","commander":"^10.0.0","typescript":"^4.9.5","@types/jest":"^29.4.0","@types/node":"^18.14.6","lint-staged":"^15.2.10","@types/mocha":"^10.0.1","@types/lodash":"^4.14.197","@commitlint/cli":"^17.4.4","jest-html-reporter":"^3.10.2","@babel/eslint-parser":"^7.19.1","eslint-plugin-import":"^2.27.5","@stryker-mutator/core":"^6.4.1","eslint-plugin-promise":"^6.1.1","eslint-plugin-sonarjs":"^0.23.0","eslint-config-prettier":"^8.7.0","@typescript-eslint/parser":"^5.62.0","eslint-config-airbnb-base":"^15.0.0","eslint-plugin-unused-imports":"^2.0.0","@commitlint/config-conventional":"^17.4.4","eslint-config-airbnb-typescript":"^17.1.0","@typescript-eslint/eslint-plugin":"^5.62.0","eslint-config-standard-with-typescript":"^34.0.0"},"_npmOperationalInternal":{"tmp":"tmp/workflow-engine-service-worker_1.0.0_1755922383678_0.9771479476269216","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@artpar/workflow-engine-service-worker","version":"1.0.1","keywords":["service-worker","chrome-extension","browser","workflow","engine","jsonata","json-template","transformation","rudder","rudderstack"],"author":{"name":"RudderStack"},"license":"MIT","_id":"@artpar/workflow-engine-service-worker@1.0.1","maintainers":[{"name":"artpar","email":"artpar@gmail.com"}],"homepage":"https://github.com/rudderlabs/rudder-workflow-engine#readme","bugs":{"url":"https://github.com/rudderlabs/rudder-workflow-engine/issues"},"dist":{"shasum":"885e99e019708c51a6d4e7e3fd7d81b9373799d7","tarball":"https://registry.npmjs.org/@artpar/workflow-engine-service-worker/-/workflow-engine-service-worker-1.0.1.tgz","fileCount":138,"integrity":"sha512-Z5YEd7STFwaGRwb0c2QI8wwAHaAzM1DxBZP6ulSoCicabaJy60wm36FGs3xgAQ2HPQcMNK80aybuoT6LXSc0oQ==","signatures":[{"sig":"MEUCIAnfK0XjuypIsN+tnjOzFs0p30ErFtUZxfEN1xSCdjzAAiEAolnVWLfemYqnZNpJCJaphztiwPVwqW5dLl+UOqHBfCQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":183153},"main":"build/index.js","types":"build/index.d.ts","exports":{".":{"types":"./build/index.d.ts","import":"./build/index.js","require":"./build/index.js"},"./service-worker":{"types":"./build/service-worker/index.d.ts","import":"./build/service-worker/index.js","require":"./build/service-worker/index.js"}},"gitHead":"7ccd193be19b4caa33adebd8f210926e0f89b948","scripts":{"lint":"npm run format && npm run lint:fix","test":"jest --coverage --verbose","build":"tsc --project tsconfig.build.json","clean":"rm -rf build","format":"prettier --write '**/*.ts' '**/*.json'","prepare":"husky install","lint:fix":"eslint . --fix","check:lint":"eslint . -f json -o reports/eslint.json || exit 0","lint:check":"eslint . || exit 1","build:clean":"npm run clean && npm run build","lint-staged":"lint-staged","test:stryker":"stryker run","test:scenario":"jest test/scenario.test.ts --verbose","jest:scenarios":"jest e2e.test.ts --verbose","test:no-logging":"LOG_LEVEL=100 jest --coverage --verbose"},"_npmUser":{"name":"artpar","email":"artpar@gmail.com"},"repository":{"url":"git+https://github.com/rudderlabs/rudder-workflow-engine.git","type":"git"},"_npmVersion":"10.9.2","description":"Service Worker workflow execution engine - Run complex data transformations in Chrome service workers and browser extensions","directories":{},"lint-staged":{"*.(ts|json|yaml)":"prettier --write"},"_nodeVersion":"22.17.0","dependencies":{"yaml":"^2.6.0","lodash":"^4.17.21","jsonata":"^2.0.5","@aws-crypto/sha256-js":"^5.2.0","@rudderstack/json-template-engine":"^0.19.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.4.3","husky":"^8.0.3","eslint":"^8.35.0","ts-jest":"^29.0.5","ts-node":"^10.9.1","prettier":"^2.8.4","commander":"^10.0.0","typescript":"^4.9.5","@types/jest":"^29.4.0","@types/node":"^18.14.6","lint-staged":"^15.2.10","@types/mocha":"^10.0.1","@types/lodash":"^4.14.197","@commitlint/cli":"^17.4.4","jest-html-reporter":"^3.10.2","@babel/eslint-parser":"^7.19.1","eslint-plugin-import":"^2.27.5","@stryker-mutator/core":"^6.4.1","eslint-plugin-promise":"^6.1.1","eslint-plugin-sonarjs":"^0.23.0","eslint-config-prettier":"^8.7.0","@typescript-eslint/parser":"^5.62.0","eslint-config-airbnb-base":"^15.0.0","eslint-plugin-unused-imports":"^2.0.0","@commitlint/config-conventional":"^17.4.4","eslint-config-airbnb-typescript":"^17.1.0","@typescript-eslint/eslint-plugin":"^5.62.0","eslint-config-standard-with-typescript":"^34.0.0"},"_npmOperationalInternal":{"tmp":"tmp/workflow-engine-service-worker_1.0.1_1755923029655_0.15825252601256468","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@artpar/workflow-engine-service-worker","version":"1.0.2","description":"Service Worker workflow execution engine - Run complex data transformations in Chrome service workers and browser extensions","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"scripts":{"test":"jest --coverage --verbose","test:no-logging":"LOG_LEVEL=100 jest --coverage --verbose","build":"tsc --project tsconfig.build.json","clean":"rm -rf build","build:clean":"npm run clean && npm run build","lint:fix":"eslint . --fix","lint:check":"eslint . || exit 1","lint-staged":"lint-staged","format":"prettier --write '**/*.ts' '**/*.json'","lint":"npm run format && npm run lint:fix","prepare":"husky install","jest:scenarios":"jest e2e.test.ts --verbose","test:scenario":"jest test/scenario.test.ts --verbose","test:stryker":"stryker run","check:lint":"eslint . -f json -o reports/eslint.json || exit 0"},"repository":{"type":"git","url":"git+https://github.com/rudderlabs/rudder-workflow-engine.git"},"keywords":["service-worker","chrome-extension","browser","workflow","engine","jsonata","json-template","transformation","rudder","rudderstack"],"author":{"name":"RudderStack"},"license":"MIT","bugs":{"url":"https://github.com/rudderlabs/rudder-workflow-engine/issues"},"homepage":"https://github.com/rudderlabs/rudder-workflow-engine#readme","devDependencies":{"@babel/eslint-parser":"^7.19.1","@commitlint/cli":"^17.4.4","@commitlint/config-conventional":"^17.4.4","@stryker-mutator/core":"^6.4.1","@types/jest":"^29.4.0","@types/lodash":"^4.14.197","@types/mocha":"^10.0.1","@types/node":"^18.14.6","@typescript-eslint/eslint-plugin":"^5.62.0","@typescript-eslint/parser":"^5.62.0","commander":"^10.0.0","eslint":"^8.35.0","eslint-config-airbnb-base":"^15.0.0","eslint-config-airbnb-typescript":"^17.1.0","eslint-config-prettier":"^8.7.0","eslint-config-standard-with-typescript":"^34.0.0","eslint-plugin-import":"^2.27.5","eslint-plugin-promise":"^6.1.1","eslint-plugin-sonarjs":"^0.23.0","eslint-plugin-unused-imports":"^2.0.0","husky":"^8.0.3","jest":"^29.4.3","jest-html-reporter":"^3.10.2","lint-staged":"^15.2.10","prettier":"^2.8.4","ts-jest":"^29.0.5","ts-node":"^10.9.1","typescript":"^4.9.5"},"dependencies":{"@aws-crypto/sha256-js":"^5.2.0","@rudderstack/json-template-engine":"^0.19.5","js-yaml":"^4.1.0","jsonata":"^2.0.5","lodash":"^4.17.21"},"lint-staged":{"*.(ts|json|yaml)":"prettier --write"},"exports":{".":{"import":"./build/index.js","require":"./build/index.js","types":"./build/index.d.ts"},"./service-worker":{"import":"./build/service-worker/index.js","require":"./build/service-worker/index.js","types":"./build/service-worker/index.d.ts"}},"_id":"@artpar/workflow-engine-service-worker@1.0.2","gitHead":"7ccd193be19b4caa33adebd8f210926e0f89b948","_nodeVersion":"22.17.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-zFBAsIixKpM8KU/AtjhUlPf9iqU9aExu0dZxCYks1f6tmYbPWzPGD4dfUtW2T7/LvpiM118U+2ThlXOW2Z+jAQ==","shasum":"c065e1105f787c88a584bcdbc7e7c7a51306e683","tarball":"https://registry.npmjs.org/@artpar/workflow-engine-service-worker/-/workflow-engine-service-worker-1.0.2.tgz","fileCount":140,"unpackedSize":186418,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHKKL0A/5Qrfckxv/ifhJ3pm0R/zBejJxU0buWg+kgExAiEAtTOA6EksAwr31FWk+dPZ/Gkzz03nznbnTZ2Ag8JvBLU="}]},"_npmUser":{"name":"artpar","email":"artpar@gmail.com"},"directories":{},"maintainers":[{"name":"artpar","email":"artpar@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/workflow-engine-service-worker_1.0.2_1755924028742_0.15737777767988814"},"_hasShrinkwrap":false}},"time":{"created":"2025-08-23T04:13:03.611Z","modified":"2025-08-23T04:40:29.186Z","1.0.0":"2025-08-23T04:13:03.913Z","1.0.1":"2025-08-23T04:23:49.852Z","1.0.2":"2025-08-23T04:40:28.972Z"},"bugs":{"url":"https://github.com/rudderlabs/rudder-workflow-engine/issues"},"author":{"name":"RudderStack"},"license":"MIT","homepage":"https://github.com/rudderlabs/rudder-workflow-engine#readme","keywords":["service-worker","chrome-extension","browser","workflow","engine","jsonata","json-template","transformation","rudder","rudderstack"],"repository":{"type":"git","url":"git+https://github.com/rudderlabs/rudder-workflow-engine.git"},"description":"Service Worker workflow execution engine - Run complex data transformations in Chrome service workers and browser extensions","maintainers":[{"name":"artpar","email":"artpar@gmail.com"}],"readme":"# RudderStack Workflow Engine - Service Worker Edition\n\nA powerful, config-driven workflow execution engine designed specifically for Chrome service workers and browser extensions. Execute complex data transformations using YAML configurations and template languages, all without server-side dependencies.\n\n## 🚀 Features\n\n- **Service Worker Native**: Built specifically for Chrome service workers and browser extensions\n- **No Node.js Dependencies**: Runs entirely in the browser/service worker context\n- **Template Languages**: Support for JSONata and JsonTemplate\n- **YAML Configuration**: Define workflows in readable YAML format\n- **Registry-Based**: All workflows and modules managed through an in-memory registry\n- **Type-Safe**: Full TypeScript support\n- **Modular Design**: Compose complex workflows from simple, reusable steps\n\n## 📦 Installation\n\n```bash\nnpm install @artpar/workflow-engine-service-worker\n```\n\n## 🎯 Quick Start\n\n### 1. Basic Setup in Service Worker\n\n```typescript\n// service-worker.ts\nimport { \n  ServiceWorkerWorkflowEngine, \n  setupServiceWorkerEnvironment \n} from '@artpar/workflow-engine-service-worker/service-worker';\n\n// Initialize the environment with workflows and modules\nsetupServiceWorkerEnvironment(\n  {\n    // Register workflow definitions\n    'transform.yaml': `\n      name: DataTransformer\n      templateType: jsonata\n      steps:\n        - name: validateInput\n          condition: $not($.userId)\n          template: |\n            $doThrow(\"userId is required\")\n        \n        - name: transform\n          template: |\n            {\n              \"id\": $.userId,\n              \"timestamp\": $millis(),\n              \"data\": $.payload\n            }\n    `\n  },\n  {\n    // Register custom functions/modules\n    'bindings': {\n      formatDate: (ts) => new Date(ts).toISOString(),\n      validateEmail: (email) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email)\n    }\n  }\n);\n\n// Use in service worker message handler\nself.addEventListener('message', async (event) => {\n  if (event.data.type === 'TRANSFORM') {\n    const engine = await ServiceWorkerWorkflowEngine.createFromRegisteredWorkflow('transform.yaml');\n    const result = await engine.execute(event.data.payload);\n    event.ports[0].postMessage({ success: true, data: result.output });\n  }\n});\n```\n\n### 2. Chrome Extension Example\n\n```typescript\n// background.js (service worker)\nimport { ServiceWorkerWorkflowEngine } from '@artpar/workflow-engine-service-worker/service-worker';\n\n// Register workflows for different extension tasks\nServiceWorkerWorkflowEngine.registerWorkflow('process-tab-data.yaml', `\n  name: TabDataProcessor\n  templateType: jsonata\n  steps:\n    - name: extractDomain\n      template: |\n        {\n          \"domain\": $substring($.url, $indexOf($.url, \"://\") + 3, $indexOf($substring($.url, $indexOf($.url, \"://\") + 3), \"/\")),\n          \"title\": $.title,\n          \"timestamp\": $millis()\n        }\n`);\n\n// Process browser tab data\nchrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => {\n  if (changeInfo.status === 'complete') {\n    const engine = await ServiceWorkerWorkflowEngine.createFromRegisteredWorkflow('process-tab-data.yaml');\n    const result = await engine.execute({\n      url: tab.url,\n      title: tab.title\n    });\n    console.log('Processed tab data:', result.output);\n  }\n});\n```\n\n## 📚 Core Concepts\n\n### Workflows\n\nWorkflows are defined in YAML and consist of:\n- **name**: Identifier for the workflow\n- **templateType**: Template language (`jsonata` or `jsontemplate`)\n- **bindings**: External functions and data to import\n- **steps**: Sequential processing steps\n\n### Steps\n\nEach step can have:\n- **name**: Step identifier (required)\n- **description**: Human-readable description\n- **condition**: JSONata expression to conditionally execute\n- **template**: Transformation logic\n- **inputTemplate**: Customize input before processing\n- **loopOverInput**: Process arrays element by element\n\n### Bindings\n\nImport external functions and data into workflows:\n\n```typescript\nServiceWorkerWorkflowEngine.registerModule('utils', {\n  // Functions\n  multiply: (a, b) => a * b,\n  \n  // Constants\n  CONFIG: {\n    maxRetries: 3,\n    timeout: 5000\n  },\n  \n  // Complex objects\n  validators: {\n    isEmail: (email) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email),\n    isURL: (url) => /^https?:\\/\\/.+/.test(url)\n  }\n});\n```\n\n## 🔧 API Reference\n\n### ServiceWorkerWorkflowEngine\n\n#### `registerWorkflow(path: string, content: string | object): void`\nRegister a workflow definition in the registry.\n\n```typescript\nServiceWorkerWorkflowEngine.registerWorkflow('my-workflow.yaml', yamlContent);\n```\n\n#### `registerModule(path: string, exports: any): void`\nRegister a module/bindings for use in workflows.\n\n```typescript\nServiceWorkerWorkflowEngine.registerModule('helpers', {\n  formatCurrency: (amount) => `$${amount.toFixed(2)}`\n});\n```\n\n#### `createFromYaml(yamlString: string, options?: Partial<WorkflowOptions>): Promise<WorkflowEngine>`\nCreate a workflow engine from YAML string.\n\n```typescript\nconst engine = await ServiceWorkerWorkflowEngine.createFromYaml(yamlContent);\nconst result = await engine.execute(inputData);\n```\n\n#### `createFromRegisteredWorkflow(path: string, options?: Partial<WorkflowOptions>): Promise<WorkflowEngine>`\nCreate a workflow engine from a registered workflow.\n\n```typescript\nconst engine = await ServiceWorkerWorkflowEngine.createFromRegisteredWorkflow('transform.yaml');\n```\n\n#### `registerBindings(bindings: Record<string, any>): void`\nRegister multiple bindings at once.\n\n```typescript\nServiceWorkerWorkflowEngine.registerBindings({\n  'math': { add: (a, b) => a + b },\n  'string': { capitalize: (s) => s.toUpperCase() }\n});\n```\n\n#### `clear(): void`\nClear all registered workflows and modules.\n\n```typescript\nServiceWorkerWorkflowEngine.clear();\n```\n\n### setupServiceWorkerEnvironment\n\nHelper function to initialize the environment with workflows and modules in one call.\n\n```typescript\nsetupServiceWorkerEnvironment(\n  workflows: Record<string, string | object>,\n  modules: Record<string, any>\n): void\n```\n\n## 🎨 Template Languages\n\n### JSONata\n\nA powerful query and transformation language for JSON data.\n\n```yaml\nname: JSONataExample\ntemplateType: jsonata\nsteps:\n  - name: transform\n    template: |\n      {\n        \"fullName\": firstName & \" \" & lastName,\n        \"age\": $number(age),\n        \"isAdult\": age >= 18,\n        \"email\": $lowercase(email)\n      }\n```\n\n[JSONata Documentation](https://jsonata.org/)\n\n### JsonTemplate\n\nA simple, intuitive template language optimized for data mapping.\n\n```yaml\nname: JsonTemplateExample\ntemplateType: jsontemplate\nsteps:\n  - name: transform\n    template: |\n      {\n        fullName: .firstName + \" \" + .lastName,\n        age: Number(.age),\n        isAdult: .age >= 18,\n        email: .email.toLowerCase()\n      }\n```\n\n[JsonTemplate Documentation](https://github.com/rudderlabs/rudder-json-template-engine)\n\n## 💡 Advanced Examples\n\n### 1. Event Processing with Validation\n\n```typescript\nconst eventProcessorYaml = `\nname: EventProcessor\ntemplateType: jsonata\nbindings:\n  - name: validators\nsteps:\n  - name: validate\n    template: |\n      (\n        $assert($.type in [\"track\", \"identify\", \"page\"], \"Invalid event type\");\n        $assert($validators.isEmail($.email), \"Invalid email\");\n        $\n      )\n  \n  - name: enrichEvent\n    template: |\n      $ ~> | $ | {\n        \"processedAt\": $millis(),\n        \"version\": \"1.0\",\n        \"metadata\": {\n          \"source\": \"browser\",\n          \"ip\": $$.context.ip\n        }\n      } |\n`;\n\nServiceWorkerWorkflowEngine.registerModule('bindings', {\n  validators: {\n    isEmail: (email) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email)\n  }\n});\n\nServiceWorkerWorkflowEngine.registerWorkflow('event-processor.yaml', eventProcessorYaml);\n```\n\n### 2. Batch Processing\n\n```typescript\nconst batchProcessorYaml = `\nname: BatchProcessor\ntemplateType: jsonata\nsteps:\n  - name: processBatch\n    loopOverInput: true\n    template: |\n      {\n        \"id\": $.id,\n        \"status\": \"processed\",\n        \"result\": $.value * 2,\n        \"timestamp\": $millis()\n      }\n`;\n\n// Process array of items\nconst engine = await ServiceWorkerWorkflowEngine.createFromYaml(batchProcessorYaml);\nconst items = [\n  { id: 1, value: 10 },\n  { id: 2, value: 20 },\n  { id: 3, value: 30 }\n];\nconst result = await engine.execute(items);\n// result.output will be an array of processed items\n```\n\n### 3. Conditional Processing\n\n```typescript\nconst conditionalWorkflowYaml = `\nname: ConditionalProcessor\ntemplateType: jsonata\nsteps:\n  - name: checkPremium\n    condition: $.user.subscription = \"premium\"\n    template: |\n      $ ~> | $ | { \"features\": [\"advanced\", \"priority\", \"support\"] } |\n    onComplete: return\n  \n  - name: checkBasic\n    condition: $.user.subscription = \"basic\"\n    template: |\n      $ ~> | $ | { \"features\": [\"standard\"] } |\n    onComplete: return\n  \n  - name: defaultFeatures\n    template: |\n      $ ~> | $ | { \"features\": [\"limited\"] } |\n`;\n```\n\n### 4. Error Handling\n\n```typescript\nconst errorHandlingYaml = `\nname: SafeProcessor\ntemplateType: jsonata\nsteps:\n  - name: riskyOperation\n    template: |\n      (\n        $data := $.data;\n        $assert($exists($data), \"Data is required\");\n        $data.value / $data.divisor\n      )\n    onError: continue\n  \n  - name: fallback\n    condition: $not($outputs.riskyOperation)\n    template: |\n      { \"error\": \"Operation failed\", \"default\": 0 }\n`;\n```\n\n## 🏗️ Architecture\n\n### Service Worker Integration\n\nThe engine is designed to work seamlessly in service worker contexts:\n\n1. **No File System**: All workflows stored in memory registry\n2. **No Dynamic Imports**: All code bundled at build time\n3. **No Node.js APIs**: Pure browser-compatible implementation\n4. **Efficient Memory Usage**: Workflows compiled once and cached\n\n### Registry System\n\nThe registry provides centralized storage for:\n- Workflow definitions (YAML/JSON)\n- Custom functions and modules\n- Configuration constants\n- Shared utilities\n\n### Path Resolution\n\nCustom path utilities handle path operations without Node.js:\n- `join()`: Combine path segments\n- `parse()`: Extract path components\n\n## 🔍 Debugging\n\n### Enable Debug Logging\n\n```typescript\nimport { logger } from '@artpar/workflow-engine-service-worker/service-worker';\n\n// Set log level\nlogger.setLogLevel(LogLevel.DEBUG);\n\n// Your workflow will now output debug information\n```\n\n### Step-by-Step Execution\n\n```yaml\nsteps:\n  - name: debug1\n    template: |\n      (\n        $log(\"Input received:\", $);\n        $\n      )\n  \n  - name: transform\n    template: |\n      { \"result\": $.value * 2 }\n  \n  - name: debug2\n    template: |\n      (\n        $log(\"Output:\", $);\n        $\n      )\n```\n\n## 🚦 Limitations\n\nSince this is a service worker implementation:\n\n1. **No File System Access**: Cannot read files from disk\n2. **No Dynamic Imports**: Cannot load modules at runtime\n3. **No Node.js APIs**: No access to Node.js-specific features\n4. **Memory Constraints**: All workflows stored in memory\n5. **Bundle Size**: All dependencies must be bundled\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## 📄 License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n## 🔗 Resources\n\n- [JSONata Documentation](https://jsonata.org/)\n- [JsonTemplate Engine](https://github.com/rudderlabs/rudder-json-template-engine)\n- [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API)\n- [Chrome Extension Development](https://developer.chrome.com/docs/extensions/mv3/service_workers/)\n\n## 💬 Support\n\n- [GitHub Issues](https://github.com/rudderlabs/rudder-workflow-engine/issues)\n- [Community Slack](https://rudderstack.com/join-rudderstack-slack-community)\n- [Documentation](https://rudderstack.com/docs/)\n\n---\n\nBuilt with ❤️ by [RudderStack](https://rudderstack.com)","readmeFilename":"README.md"}