From 63a3dc05b3eb886da4e8284d42b368a1be3cfe26 Mon Sep 17 00:00:00 2001 From: Giselle van Dongen Date: Fri, 21 Jun 2024 12:55:15 +0200 Subject: [PATCH] Formatting TS code and cleanup (#425) --- .../concepts/invocations/DelayedCalls.java | 22 - .../concepts/invocations/OneWayCalls.java | 27 - .../java/concepts/invocations/RpcCalls.java | 26 - code_snippets/ts/package-lock.json | 1726 ++++++++++++++++- code_snippets/ts/package.json | 10 +- .../ts/src/concepts/food_ordering.ts | 86 +- .../src/concepts/food_ordering_awakeables.ts | 45 - .../src/concepts/food_ordering_functions.ts | 43 - .../ts/src/concepts/food_ordering_rpc.ts | 43 - .../src/concepts/food_ordering_side_effect.ts | 47 - .../ts/src/concepts/food_ordering_state.ts | 47 - .../ts/src/concepts/invocations/delayed.ts | 16 +- .../concepts/invocations/ingress/delayed.ts | 25 +- .../concepts/invocations/ingress/one_way.ts | 23 +- .../src/concepts/invocations/ingress/rpc.ts | 26 +- .../ts/src/concepts/invocations/one_way.ts | 19 +- .../ts/src/concepts/invocations/rpc.ts | 19 +- .../ts/src/concepts/invocations/utils.ts | 71 +- code_snippets/ts/src/concepts/services.ts | 110 +- code_snippets/ts/src/concepts/utils.ts | 61 +- .../ts/src/concepts/virtual_objects.ts | 78 +- code_snippets/ts/src/concepts/workflow.ts | 94 +- code_snippets/ts/src/develop/awakeable.ts | 54 +- .../ts/src/develop/clients/ingress.ts | 110 +- code_snippets/ts/src/develop/clients/utils.ts | 38 +- .../ts/src/develop/durable_timers.ts | 18 +- .../ts/src/develop/error_handling.ts | 18 +- .../ts/src/develop/journaling_results.ts | 97 +- code_snippets/ts/src/develop/kafka.ts | 16 +- code_snippets/ts/src/develop/my_service.ts | 21 +- .../ts/src/develop/my_virtual_object.ts | 39 +- .../ts/src/develop/service_communication.ts | 113 +- code_snippets/ts/src/develop/serving.ts | 51 +- code_snippets/ts/src/develop/state.ts | 44 +- code_snippets/ts/src/develop/workflow.ts | 31 +- .../ts/src/develop/workflows/service.ts | 40 +- .../ts/src/develop/workflows/signup.ts | 72 +- .../ts/src/develop/workflows/submit.ts | 62 +- code_snippets/ts/src/get_started/tour.ts | 115 +- code_snippets/ts/src/operate/monitoring.ts | 22 +- .../use_cases/async_tasks/fan_out_worker.ts | 70 +- .../simple_async_task/async_task_service.ts | 24 +- .../simple_async_task/task_submitter.ts | 38 +- .../async_tasks/sync_to_async/client.ts | 70 +- .../sync_to_async/data_preparation_service.ts | 68 +- .../ts/src/use_cases/event_processing.ts | 88 +- .../ts/src/use_cases/events_state.ts | 81 +- code_snippets/ts/src/use_cases/idempotency.ts | 29 +- .../ts/src/use_cases/idempotency_utils.ts | 12 +- .../ts/src/use_cases/role_updater.ts | 121 +- .../ts/src/use_cases/signup_workflow.ts | 112 +- code_snippets/ts/src/use_cases/submit.ts | 32 +- code_snippets/ts/tsconfig.json | 30 +- docs/concepts/durable_building_blocks.mdx | 10 +- docs/concepts/invocations.mdx | 76 +- docs/develop/ts/journaling-results.mdx | 53 +- 56 files changed, 2891 insertions(+), 1648 deletions(-) delete mode 100644 code_snippets/ts/src/concepts/food_ordering_awakeables.ts delete mode 100644 code_snippets/ts/src/concepts/food_ordering_functions.ts delete mode 100644 code_snippets/ts/src/concepts/food_ordering_rpc.ts delete mode 100644 code_snippets/ts/src/concepts/food_ordering_side_effect.ts delete mode 100644 code_snippets/ts/src/concepts/food_ordering_state.ts diff --git a/code_snippets/java/src/main/java/concepts/invocations/DelayedCalls.java b/code_snippets/java/src/main/java/concepts/invocations/DelayedCalls.java index 75342054..7e699b89 100644 --- a/code_snippets/java/src/main/java/concepts/invocations/DelayedCalls.java +++ b/code_snippets/java/src/main/java/concepts/invocations/DelayedCalls.java @@ -4,7 +4,6 @@ import dev.restate.sdk.annotation.Handler; import dev.restate.sdk.annotation.Service; import dev.restate.sdk.client.Client; -import develop.MyWorkflowClient; import java.time.Duration; @Service @@ -19,20 +18,6 @@ public void myRestateHandler(Context ctx) { .send(Duration.ofMillis(1000)) // focus .greet("Hi"); - - // focus - GreetCounterObjectClient.fromContext(ctx, "Mary") - // focus - .send(Duration.ofMillis(1000)) - // focus - .greet("Hi"); - - // focus - MyWorkflowClient.fromContext(ctx, "wf-id-1") - // focus - .send(Duration.ofMillis(1000)) - // focus - .run("input"); } // @@ -47,13 +32,6 @@ public void myJavaHandler(Context ctx) { .send(Duration.ofMillis(1000)) // focus .greet("Hi"); - - // focus - GreetCounterObjectClient.fromClient(restate, "Mary") - // focus - .send(Duration.ofMillis(1000)) - // focus - .greet("Hi"); } // } diff --git a/code_snippets/java/src/main/java/concepts/invocations/OneWayCalls.java b/code_snippets/java/src/main/java/concepts/invocations/OneWayCalls.java index 300a5462..cd88df60 100644 --- a/code_snippets/java/src/main/java/concepts/invocations/OneWayCalls.java +++ b/code_snippets/java/src/main/java/concepts/invocations/OneWayCalls.java @@ -4,7 +4,6 @@ import dev.restate.sdk.annotation.Handler; import dev.restate.sdk.annotation.Service; import dev.restate.sdk.client.Client; -import develop.MyWorkflowClient; @Service public class OneWayCalls { @@ -18,20 +17,6 @@ public void myRestateHandler(Context ctx) { .send() // focus .greet("Hi"); - - // focus - GreetCounterObjectClient.fromContext(ctx, "Mary") - // focus - .send() - // focus - .greet("Hi"); - - // focus - MyWorkflowClient.fromContext(ctx, "wf-id-1") - // focus - .send() - // focus - .run("input"); } // @@ -46,18 +31,6 @@ public void myJavaHandler(Context ctx) { .send() // focus .greet("Hi"); - - // focus - GreetCounterObjectClient.fromClient(restate, "Mary") - // focus - .send() - // focus - .greet("Hi"); - - // focus - MyWorkflowClient.fromClient(restate, "wf-id-1") - // focus - .submit("input"); } // } diff --git a/code_snippets/java/src/main/java/concepts/invocations/RpcCalls.java b/code_snippets/java/src/main/java/concepts/invocations/RpcCalls.java index 3acabed5..1ee55fc9 100644 --- a/code_snippets/java/src/main/java/concepts/invocations/RpcCalls.java +++ b/code_snippets/java/src/main/java/concepts/invocations/RpcCalls.java @@ -4,7 +4,6 @@ import dev.restate.sdk.annotation.Handler; import dev.restate.sdk.annotation.Service; import dev.restate.sdk.client.Client; -import develop.MyWorkflowClient; @Service public class RpcCalls { @@ -20,24 +19,6 @@ public void myRestateHandler(Context ctx) { .greet("Hi") // focus .await(); - - // focus - int count = - // focus - GreetCounterObjectClient.fromContext(ctx, "Mary") - // focus - .greet("Hi") - // focus - .await(); - - // focus - String result = - // focus - MyWorkflowClient.fromContext(ctx, "wf-id-1") - // focus - .run("input") - // focus - .await(); } // @@ -52,13 +33,6 @@ public void myJavaHandler(Context ctx) { GreeterServiceClient.fromClient(restate) // focus .greet("Hi"); - - // focus - int count = - // focus - GreetCounterObjectClient.fromClient(restate, "Mary") - // focus - .greet("Hi"); } // diff --git a/code_snippets/ts/package-lock.json b/code_snippets/ts/package-lock.json index 8257c057..17261f4d 100644 --- a/code_snippets/ts/package-lock.json +++ b/code_snippets/ts/package-lock.json @@ -16,7 +16,11 @@ "devDependencies": { "@types/express": "^4.17.21", "@types/node": "^20.12.7", + "@typescript-eslint/eslint-plugin": "^5.53.0", + "@typescript-eslint/parser": "^5.53.0", "esbuild": "^0.18.12", + "eslint": "^8.35.0", + "prettier": "^2.8.4", "ts-node-dev": "^1.1.1", "typescript": "^5.0.2" } @@ -1019,6 +1023,190 @@ "node": ">=12" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@restatedev/restate-cdk": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@restatedev/restate-cdk/-/restate-cdk-1.0.0.tgz", @@ -1661,6 +1849,12 @@ "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", "dev": true }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -1688,6 +1882,12 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -1721,149 +1921,533 @@ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", "dev": true }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": ">= 0.6" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "ms": "2.1.2" }, "engines": { - "node": ">= 8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/aws-cdk": { - "version": "2.144.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.144.0.tgz", - "integrity": "sha512-qsTZGCceKi15oOYbWvWpIZNBHRZa+WTV5IIN20leQV9PVRxzHGN58VCOIAiyT1+CncDYjY9grLXEGAOuKRynFQ==", - "peer": true, - "bin": { - "cdk": "bin/cdk" + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 14.15.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "optionalDependencies": { - "fsevents": "2.3.2" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/aws-cdk-lib": { - "version": "2.144.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.144.0.tgz", - "integrity": "sha512-DpyIyTs8NHX6WgAyYM2mGorirIk+eTjWzXGQRfzAe40qkwcqsb5Ax4JEl5gz1OEo9QIJIgWDtmImgWN0tUbILA==", - "bundleDependencies": [ - "@balena/dockerignore", - "case", - "fs-extra", - "ignore", - "jsonschema", - "minimatch", - "punycode", - "semver", - "table", - "yaml", - "mime-types" - ], - "peer": true, + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.202", - "@aws-cdk/asset-kubectl-v20": "^2.1.2", - "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.3", - "@balena/dockerignore": "^1.0.2", - "case": "1.6.3", - "fs-extra": "^11.2.0", - "ignore": "^5.3.1", - "jsonschema": "^1.4.1", - "mime-types": "^2.1.35", - "minimatch": "^3.1.2", - "punycode": "^2.3.1", - "semver": "^7.6.0", - "table": "^6.8.2", - "yaml": "1.10.2" + "ms": "2.1.2" }, "engines": { - "node": ">= 14.15.0" + "node": ">=6.0" }, - "peerDependencies": { - "constructs": "^10.0.0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { - "version": "1.0.2", - "inBundle": true, - "license": "Apache-2.0", - "peer": true + "node_modules/@typescript-eslint/parser/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, - "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.13.0", - "inBundle": true, - "license": "MIT", - "peer": true, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/aws-cdk-lib/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "peer": true, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/aws-cdk-lib/node_modules/ansi-styles": { - "version": "4.3.0", - "inBundle": true, - "license": "MIT", - "peer": true, + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/aws-cdk-lib/node_modules/astral-regex": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "peer": true, + "node_modules/@typescript-eslint/type-utils/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk": { + "version": "2.144.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.144.0.tgz", + "integrity": "sha512-qsTZGCceKi15oOYbWvWpIZNBHRZa+WTV5IIN20leQV9PVRxzHGN58VCOIAiyT1+CncDYjY9grLXEGAOuKRynFQ==", + "peer": true, + "bin": { + "cdk": "bin/cdk" + }, + "engines": { + "node": ">= 14.15.0" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/aws-cdk-lib": { + "version": "2.144.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.144.0.tgz", + "integrity": "sha512-DpyIyTs8NHX6WgAyYM2mGorirIk+eTjWzXGQRfzAe40qkwcqsb5Ax4JEl5gz1OEo9QIJIgWDtmImgWN0tUbILA==", + "bundleDependencies": [ + "@balena/dockerignore", + "case", + "fs-extra", + "ignore", + "jsonschema", + "minimatch", + "punycode", + "semver", + "table", + "yaml", + "mime-types" + ], + "peer": true, + "dependencies": { + "@aws-cdk/asset-awscli-v1": "^2.2.202", + "@aws-cdk/asset-kubectl-v20": "^2.1.2", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.3", + "@balena/dockerignore": "^1.0.2", + "case": "1.6.3", + "fs-extra": "^11.2.0", + "ignore": "^5.3.1", + "jsonschema": "^1.4.1", + "mime-types": "^2.1.35", + "minimatch": "^3.1.2", + "punycode": "^2.3.1", + "semver": "^7.6.0", + "table": "^6.8.2", + "yaml": "1.10.2" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "constructs": "^10.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { + "version": "1.0.2", + "inBundle": true, + "license": "Apache-2.0", + "peer": true + }, + "node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.13.0", + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -2271,6 +2855,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -2295,6 +2904,24 @@ "fsevents": "~2.3.2" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2348,6 +2975,20 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -2365,6 +3006,12 @@ "ms": "2.0.0" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -2407,6 +3054,30 @@ "node": ">=0.3.1" } }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/dynamic-dedupe": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz", @@ -2490,6 +3161,195 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -2539,6 +3399,40 @@ "node": ">= 0.10.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, "node_modules/fast-xml-parser": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", @@ -2561,6 +3455,15 @@ "fxparser": "src/cli/cli.js" } }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -2584,6 +3487,18 @@ "node": "^12.20 || >= 14.13" } }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2613,6 +3528,58 @@ "node": ">= 0.8" } }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -2719,6 +3686,41 @@ "node": ">= 6" } }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -2730,6 +3732,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -2800,6 +3817,40 @@ "node": ">=0.10.0" } }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2875,9 +3926,97 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "engines": { - "node": ">=0.12.0" + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -2897,6 +4036,15 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -2905,6 +4053,19 @@ "node": ">= 0.6" } }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -2973,6 +4134,18 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -3055,6 +4228,65 @@ "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -3063,6 +4295,15 @@ "node": ">= 0.8" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -3072,6 +4313,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -3083,6 +4333,15 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -3095,6 +4354,30 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -3107,6 +4390,15 @@ "node": ">= 0.10" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -3121,6 +4413,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -3172,6 +4484,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -3185,6 +4516,29 @@ "rimraf": "bin.js" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -3209,6 +4563,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -3272,6 +4638,27 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", @@ -3289,6 +4676,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3316,6 +4712,18 @@ "node": ">= 0.8" } }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -3340,6 +4748,18 @@ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", "peer": true }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -3352,6 +4772,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3459,6 +4885,51 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "peer": true }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -3498,6 +4969,15 @@ "node": ">= 0.8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -3536,6 +5016,30 @@ "node": ">= 8" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3559,6 +5063,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/code_snippets/ts/package.json b/code_snippets/ts/package.json index c6ac5c03..784a4e19 100644 --- a/code_snippets/ts/package.json +++ b/code_snippets/ts/package.json @@ -10,7 +10,9 @@ "bundle": "esbuild src/app.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js", "postbundle": "cd dist && zip -r index.zip index.js*", "app": "node ./dist/app.js", - "app-dev": "ts-node-dev --watch src --respawn --transpile-only ./src/app.ts" + "app-dev": "ts-node-dev --watch src --respawn --transpile-only ./src/app.ts", + "lint": "eslint --ignore-path .eslintignore --ext .ts .", + "format": "prettier --ignore-path .eslintignore --write \"**/*.+(js|ts|json)\"" }, "dependencies": { "@restatedev/restate-cdk": "^1.0.0", @@ -23,6 +25,10 @@ "@types/node": "^20.12.7", "esbuild": "^0.18.12", "ts-node-dev": "^1.1.1", - "typescript": "^5.0.2" + "typescript": "^5.0.2", + "@typescript-eslint/eslint-plugin": "^5.53.0", + "@typescript-eslint/parser": "^5.53.0", + "eslint": "^8.35.0", + "prettier": "^2.8.4" } } diff --git a/code_snippets/ts/src/concepts/food_ordering.ts b/code_snippets/ts/src/concepts/food_ordering.ts index 31fa98d0..3a901259 100644 --- a/code_snippets/ts/src/concepts/food_ordering.ts +++ b/code_snippets/ts/src/concepts/food_ordering.ts @@ -1,42 +1,66 @@ -import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; -import {deliveryManager, Order, paymentClnt, restaurant, Status} from "./utils"; +import { ObjectContext } from "@restatedev/restate-sdk"; +import { + deliveryManager, + Order, + paymentClnt, + restaurant, + Status, +} from "./utils"; // +// async function process(ctx: ObjectContext, order: Order) { + // + // 1. Set status + // + ctx.set("status", Status.CREATED); + // - // 1. Set status - ctx.set("status", Status.CREATED); + // 2. Handle payment + // + const token = ctx.rand.uuidv4(); + const paid = await ctx.run(() => + paymentClnt.charge(order.id, token, order.totalCost) + ); + // - // 2. Handle payment - const token = ctx.rand.uuidv4(); - const paid = await ctx.run(() => - paymentClnt.charge(order.id, token, order.totalCost) - ); + if (!paid) { + // + ctx.set("status", Status.REJECTED); + // + return; + } - if (!paid) { - ctx.set("status", Status.REJECTED); - return; - } + // 3. Wait until the requested preparation time + // + ctx.set("status", Status.SCHEDULED); + // + await ctx.sleep(order.deliveryDelay); - // 3. Wait until the requested preparation time - ctx.set("status", Status.SCHEDULED); - await ctx.sleep(order.deliveryDelay); + // 4. Trigger preparation + // + const preparationPromise = ctx.awakeable(); + // + await ctx.run(() => restaurant.prepare(order.id, preparationPromise.id)); + // + // + // + ctx.set("status", Status.IN_PREPARATION); + // - // 4. Trigger preparation - const preparationPromise = ctx.awakeable(); - await ctx.run(() => - restaurant.prepare(order.id, preparationPromise.id) - ); - ctx.set("status", Status.IN_PREPARATION); + // + await preparationPromise.promise; + // + // + ctx.set("status", Status.SCHEDULING_DELIVERY); + // - await preparationPromise.promise; - ctx.set("status", Status.SCHEDULING_DELIVERY); - - // 5. Find a driver and start delivery - await ctx.objectClient(deliveryManager, order.id) - .startDelivery(order); - ctx.set("status", Status.DELIVERED); + // 5. Find a driver and start delivery + // + await ctx.objectClient(deliveryManager, order.id).startDelivery(order); + // + // + ctx.set("status", Status.DELIVERED); + // } // - diff --git a/code_snippets/ts/src/concepts/food_ordering_awakeables.ts b/code_snippets/ts/src/concepts/food_ordering_awakeables.ts deleted file mode 100644 index 981f73a2..00000000 --- a/code_snippets/ts/src/concepts/food_ordering_awakeables.ts +++ /dev/null @@ -1,45 +0,0 @@ -import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; -import {deliveryManager, Order, paymentClnt, restaurant, Status} from "./utils"; - - -// -async function process(ctx: ObjectContext, order: Order) { - - // 1. Set status - ctx.set("status", Status.CREATED); - - // 2. Handle payment - const token = ctx.rand.uuidv4(); - const paid = await ctx.run(() => - paymentClnt.charge(order.id, token, order.totalCost) - ); - - if (!paid) { - ctx.set("status", Status.REJECTED); - return; - } - - // 3. Wait until the requested preparation time - ctx.set("status", Status.SCHEDULED); - await ctx.sleep(order.deliveryDelay); - - // 4. Trigger preparation - // mark - const preparationPromise = ctx.awakeable(); - await ctx.run(() => - // mark - restaurant.prepare(order.id, preparationPromise.id) - ); - ctx.set("status", Status.IN_PREPARATION); - - // mark - await preparationPromise.promise; - ctx.set("status", Status.SCHEDULING_DELIVERY); - - // 5. Find a driver and start delivery - await ctx.objectClient(deliveryManager, order.id) - .startDelivery(order); - ctx.set("status", Status.DELIVERED); -} -// \ No newline at end of file diff --git a/code_snippets/ts/src/concepts/food_ordering_functions.ts b/code_snippets/ts/src/concepts/food_ordering_functions.ts deleted file mode 100644 index b07c2edd..00000000 --- a/code_snippets/ts/src/concepts/food_ordering_functions.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; -import {deliveryManager, Order, paymentClnt, restaurant, Status} from "./utils"; - -// -// mark -async function process(ctx: ObjectContext, order: Order) { - - // 1. Set status - ctx.set("status", Status.CREATED); - - // 2. Handle payment - const token = ctx.rand.uuidv4(); - const paid = await ctx.run(() => - paymentClnt.charge(order.id, token, order.totalCost) - ); - - if (!paid) { - ctx.set("status", Status.REJECTED); - return; - } - - // 3. Wait until the requested preparation time - ctx.set("status", Status.SCHEDULED); - await ctx.sleep(order.deliveryDelay); - - // 4. Trigger preparation - const preparationPromise = ctx.awakeable(); - await ctx.run(() => - restaurant.prepare(order.id, preparationPromise.id) - ); - ctx.set("status", Status.IN_PREPARATION); - - await preparationPromise.promise; - ctx.set("status", Status.SCHEDULING_DELIVERY); - - // 5. Find a driver and start delivery - await ctx.objectClient(deliveryManager, order.id) - .startDelivery(order); - ctx.set("status", Status.DELIVERED); -// mark -} -// \ No newline at end of file diff --git a/code_snippets/ts/src/concepts/food_ordering_rpc.ts b/code_snippets/ts/src/concepts/food_ordering_rpc.ts deleted file mode 100644 index 2d4c3f78..00000000 --- a/code_snippets/ts/src/concepts/food_ordering_rpc.ts +++ /dev/null @@ -1,43 +0,0 @@ -import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; -import {deliveryManager, Order, paymentClnt, restaurant, Status} from "./utils"; - -// -async function process(ctx: ObjectContext, order: Order) { - - // 1. Set status - ctx.set("status", Status.CREATED); - - // 2. Handle payment - const token = ctx.rand.uuidv4(); - const paid = await ctx.run(() => - paymentClnt.charge(order.id, token, order.totalCost) - ); - - if (!paid) { - ctx.set("status", Status.REJECTED); - return; - } - - // 3. Wait until the requested preparation time - ctx.set("status", Status.SCHEDULED); - await ctx.sleep(order.deliveryDelay); - - // 4. Trigger preparation - const preparationPromise = ctx.awakeable(); - await ctx.run(() => - restaurant.prepare(order.id, preparationPromise.id) - ); - ctx.set("status", Status.IN_PREPARATION); - - await preparationPromise.promise; - ctx.set("status", Status.SCHEDULING_DELIVERY); - - // 5. Find a driver and start delivery - // mark - await ctx.objectClient(deliveryManager, order.id) - // mark - .startDelivery(order); - ctx.set("status", Status.DELIVERED); -} -// \ No newline at end of file diff --git a/code_snippets/ts/src/concepts/food_ordering_side_effect.ts b/code_snippets/ts/src/concepts/food_ordering_side_effect.ts deleted file mode 100644 index 14d46380..00000000 --- a/code_snippets/ts/src/concepts/food_ordering_side_effect.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; -import {deliveryManager, Order, paymentClnt, restaurant, Status} from "./utils"; - -// -async function process(ctx: ObjectContext, order: Order) { - - // 1. Set status - ctx.set("status", Status.CREATED); - - // 2. Handle payment - const token = ctx.rand.uuidv4(); - // mark - const paid = await ctx.run(() => - // mark - paymentClnt.charge(order.id, token, order.totalCost) - // mark - ); - - if (!paid) { - ctx.set("status", Status.REJECTED); - return; - } - - // 3. Wait until the requested preparation time - ctx.set("status", Status.SCHEDULED); - await ctx.sleep(order.deliveryDelay); - - // 4. Trigger preparation - const preparationPromise = ctx.awakeable(); - // mark - await ctx.run(() => - // mark - restaurant.prepare(order.id, preparationPromise.id) - // mark - ); - ctx.set("status", Status.IN_PREPARATION); - - await preparationPromise.promise; - ctx.set("status", Status.SCHEDULING_DELIVERY); - - // 5. Find a driver and start delivery - await ctx.objectClient(deliveryManager, order.id) - .startDelivery(order); - ctx.set("status", Status.DELIVERED); -} -// \ No newline at end of file diff --git a/code_snippets/ts/src/concepts/food_ordering_state.ts b/code_snippets/ts/src/concepts/food_ordering_state.ts deleted file mode 100644 index 9a90fdee..00000000 --- a/code_snippets/ts/src/concepts/food_ordering_state.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; -import {deliveryManager, Order, paymentClnt, restaurant, Status} from "./utils"; - -// -async function process(ctx: ObjectContext, order: Order) { - - // 1. Set status - // mark - ctx.set("status", Status.CREATED); - - // 2. Handle payment - const token = ctx.rand.uuidv4(); - const paid = await ctx.run(() => - paymentClnt.charge(order.id, token, order.totalCost) - ); - - if (!paid) { - // mark - ctx.set("status", Status.REJECTED); - return; - } - - // 3. Wait until the requested preparation time - // mark - ctx.set("status", Status.SCHEDULED); - await ctx.sleep(order.deliveryDelay); - - // 4. Trigger preparation - const preparationPromise = ctx.awakeable(); - await ctx.run(() => - restaurant.prepare(order.id, preparationPromise.id) - ); - // mark - ctx.set("status", Status.IN_PREPARATION); - - await preparationPromise.promise; - // mark - ctx.set("status", Status.SCHEDULING_DELIVERY); - - // 5. Find a driver and start delivery - await ctx.objectClient(deliveryManager, order.id) - .startDelivery(order); - // mark - ctx.set("status", Status.DELIVERED); -} -// \ No newline at end of file diff --git a/code_snippets/ts/src/concepts/invocations/delayed.ts b/code_snippets/ts/src/concepts/invocations/delayed.ts index ae37ffe2..5f2f6b40 100644 --- a/code_snippets/ts/src/concepts/invocations/delayed.ts +++ b/code_snippets/ts/src/concepts/invocations/delayed.ts @@ -1,13 +1,13 @@ import * as restate from "@restatedev/restate-sdk"; -import {greetCounterObject, greeterService, myWorkflow} from "./utils"; +import { greetCounter, greeter } from "./utils"; // async function myRestateHandler(ctx: restate.Context) { - // focus(1:5) - ctx.serviceSendClient(greeterService, { delay: 1000 }) - .greet({greeting: "Hi"}); - - ctx.objectSendClient(greetCounterObject, "Mary", { delay: 1000 }) - .greet({greeting: "Hi"}); + // focus + ctx + // focus + .serviceSendClient(greeter, { delay: 1000 }) + // focus + .greet({ greeting: "Hi" }); } -// \ No newline at end of file +// diff --git a/code_snippets/ts/src/concepts/invocations/ingress/delayed.ts b/code_snippets/ts/src/concepts/invocations/ingress/delayed.ts index d0249b70..5d4158f8 100644 --- a/code_snippets/ts/src/concepts/invocations/ingress/delayed.ts +++ b/code_snippets/ts/src/concepts/invocations/ingress/delayed.ts @@ -1,17 +1,16 @@ import * as restate from "@restatedev/restate-sdk-clients"; -import {greetCounterObject, greeterService} from "../utils"; -import {SendOpts} from "@restatedev/restate-sdk-clients"; +import { greetCounter, greeter } from "../utils"; +import { SendOpts } from "@restatedev/restate-sdk-clients"; // const myPlainTSFunction = async () => { - // focus(1:8) - // From any TS code: - const rs = restate.connect({ url: "http://localhost:8080" }) - - const { invocationId } = await rs.serviceSendClient(greeterService) - .greet({greeting: "Hi"}, SendOpts.from({ delay: 1000 })); - - await rs.objectSendClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}, SendOpts.from({ delay: 1000 })); -} -// \ No newline at end of file + // focus + const rs = restate.connect({ url: "http://localhost:8080" }); + // focus + await rs + // focus + .serviceSendClient(greeter) + // focus + .greet({ greeting: "Hi" }, SendOpts.from({ delay: 1000 })); +}; +// diff --git a/code_snippets/ts/src/concepts/invocations/ingress/one_way.ts b/code_snippets/ts/src/concepts/invocations/ingress/one_way.ts index e5cbe2ff..581dcac1 100644 --- a/code_snippets/ts/src/concepts/invocations/ingress/one_way.ts +++ b/code_snippets/ts/src/concepts/invocations/ingress/one_way.ts @@ -1,16 +1,15 @@ import * as restate from "@restatedev/restate-sdk-clients"; -import {greetCounterObject, greeterService} from "../utils"; +import { greetCounter, greeter } from "../utils"; // const myPlainTSFunction = async () => { - // focus(1:9) - // From any TS code: - const rs = restate.connect({url: "http://localhost:8080"}) - - const sendHandle = await rs.serviceSendClient(greeterService) - .greet({greeting: "Hi"}); - - const sendHandle2 = await rs.objectSendClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}); -} -// \ No newline at end of file + // focus + const rs = restate.connect({ url: "http://localhost:8080" }); + // focus + await rs + // focus + .serviceSendClient(greeter) + // focus + .greet({ greeting: "Hi" }); +}; +// diff --git a/code_snippets/ts/src/concepts/invocations/ingress/rpc.ts b/code_snippets/ts/src/concepts/invocations/ingress/rpc.ts index f5c1f7e9..9d497024 100644 --- a/code_snippets/ts/src/concepts/invocations/ingress/rpc.ts +++ b/code_snippets/ts/src/concepts/invocations/ingress/rpc.ts @@ -1,19 +1,15 @@ import * as restate from "@restatedev/restate-sdk-clients"; -import {greetCounterObject, greeterService, myWorkflow} from "../utils"; +import { greetCounter, greeter, myWorkflow } from "../utils"; // const myPlainTSFunction = async () => { - // focus(1:11) - // From any TS code: - const rs = restate.connect({ url: "http://localhost:8080" }); - - const greet = await rs.serviceClient(greeterService) - .greet({ greeting: "Hi" }); - - const count = await rs.objectClient(greetCounterObject, "Mary") - .greet({ greeting: "Hi" }); - - const result = await rs.workflowClient(myWorkflow, "wf-id-1") - .workflowSubmit({ input: "Hi" }); -} -// \ No newline at end of file + // focus + const rs = restate.connect({ url: "http://localhost:8080" }); + // focus + const greet = await rs + // focus + .serviceClient(greeter) + // focus + .greet({ greeting: "Hi" }); +}; +// diff --git a/code_snippets/ts/src/concepts/invocations/one_way.ts b/code_snippets/ts/src/concepts/invocations/one_way.ts index f39a182d..a57821c8 100644 --- a/code_snippets/ts/src/concepts/invocations/one_way.ts +++ b/code_snippets/ts/src/concepts/invocations/one_way.ts @@ -1,16 +1,13 @@ import * as restate from "@restatedev/restate-sdk"; -import {greetCounterObject, greeterService, myWorkflow} from "./utils"; +import { greetCounter, greeter, myWorkflow } from "./utils"; // async function myRestateHandler(ctx: restate.Context) { - // focus(1:8) - ctx.serviceSendClient(greeterService) - .greet({greeting: "Hi"}); - - ctx.objectSendClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}); - - ctx.workflowSendClient(myWorkflow, "wf-id-1") - .run({input: "Hi"}); + // focus + ctx + // focus + .serviceSendClient(greeter) + // focus + .greet({ greeting: "Hi" }); } -// \ No newline at end of file +// diff --git a/code_snippets/ts/src/concepts/invocations/rpc.ts b/code_snippets/ts/src/concepts/invocations/rpc.ts index 13c9f127..ae0d0bec 100644 --- a/code_snippets/ts/src/concepts/invocations/rpc.ts +++ b/code_snippets/ts/src/concepts/invocations/rpc.ts @@ -1,16 +1,13 @@ import * as restate from "@restatedev/restate-sdk"; -import {greetCounterObject, greeterService, myWorkflow} from "./utils"; +import { greetCounter, greeter, myWorkflow } from "./utils"; // async function myRestateHandler(ctx: restate.Context) { - // focus(1:8) - const greet = await ctx.serviceClient(greeterService) - .greet({greeting: "Hi"}); - - const count = await ctx.objectClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}); - - const result = await ctx.workflowClient(myWorkflow, "wf-id-1") - .run({input: "Hi"}); + // focus + const greet = await ctx + // focus + .serviceClient(greeter) + // focus + .greet({ greeting: "Hi" }); } -// \ No newline at end of file +// diff --git a/code_snippets/ts/src/concepts/invocations/utils.ts b/code_snippets/ts/src/concepts/invocations/utils.ts index bcbbd57c..f6dbe004 100644 --- a/code_snippets/ts/src/concepts/invocations/utils.ts +++ b/code_snippets/ts/src/concepts/invocations/utils.ts @@ -1,38 +1,43 @@ import * as restate from "@restatedev/restate-sdk"; -export const greeterService = restate.service({ - name: "greeterService", - handlers:{ - greet: async (ctx: restate.Context, request: { greeting?: string }) => { - return `Hello ${request.greeting}`; - } - } -}) +export const greeter = restate.service({ + name: "greeterService", + handlers: { + greet: async (ctx: restate.Context, request: { greeting?: string }) => { + return `Hello ${request.greeting}`; + }, + }, +}); - -export const greetCounterObject = restate.object({ - name: "greetCounterObject", - handlers:{ - greet: async (ctx: restate.ObjectContext, request: { greeting?: string }) => { - let count = (await ctx.get("count")) ?? 0; - count++; - ctx.set("count", count); - return count; - } - } -}) +export const greetCounter = restate.object({ + name: "greetCounterObject", + handlers: { + greet: async ( + ctx: restate.ObjectContext, + request: { greeting?: string } + ) => { + let count = (await ctx.get("count")) ?? 0; + count++; + ctx.set("count", count); + return count; + }, + }, +}); export const myWorkflow = restate.workflow({ - name: "greetCounterObject", - handlers:{ - run: async (ctx: restate.WorkflowContext, request: { input?: string }) => { - let count = (await ctx.get("count")) ?? 0; - count++; - ctx.set("count", count); - return count; - }, - myOtherHandler: async (ctx: restate.WorkflowSharedContext, request: { input?: string })=> { - return ""; - } - } -}) \ No newline at end of file + name: "greetCounterObject", + handlers: { + run: async (ctx: restate.WorkflowContext, request: { input?: string }) => { + let count = (await ctx.get("count")) ?? 0; + count++; + ctx.set("count", count); + return count; + }, + myOtherHandler: async ( + ctx: restate.WorkflowSharedContext, + request: { input?: string } + ) => { + return ""; + }, + }, +}); diff --git a/code_snippets/ts/src/concepts/services.ts b/code_snippets/ts/src/concepts/services.ts index 4cd7ecf7..08c3e9fd 100644 --- a/code_snippets/ts/src/concepts/services.ts +++ b/code_snippets/ts/src/concepts/services.ts @@ -6,83 +6,89 @@ // import * as restate from "@restatedev/restate-sdk"; -import {Context} from "@restatedev/restate-sdk"; +import { Context } from "@restatedev/restate-sdk"; // export const roleUpdateService = restate.service({ - // - name: "roleUpdate", - // - handlers: { - applyRoleUpdate: async (ctx: Context, update: UpdateRequest) => { - // - const { userId, role, permissions } = update; + // + name: "roleUpdate", + // + handlers: { + applyRoleUpdate: async (ctx: Context, update: UpdateRequest) => { + // + const { userId, role, permissions } = update; - // - const success = await ctx.run(() => applyUserRole(userId, role)); - // - // - if (!success) { - return; - } - // + // + const success = await ctx.run(() => applyUserRole(userId, role)); + // + // + if (!success) { + return; + } + // - // - for (const permission of permissions) { - // - // - await ctx.run(() => applyPermission(userId, permission)); - // - // - } - // - } - } + // + for (const permission of permissions) { + // + // + await ctx.run(() => applyPermission(userId, permission)); + // + // + } + // + }, + }, }); restate.endpoint().bind(roleUpdateService).listen(); // export type UserRole = { - roleKey: string; - roleDescription: string; + roleKey: string; + roleDescription: string; }; export type Permission = { - permissionKey: string; - setting: string; + permissionKey: string; + setting: string; }; export type UpdateRequest = { - userId: string; - role: UserRole; - permissions: Permission[]; + userId: string; + role: UserRole; + permissions: Permission[]; }; const killProcess: boolean = Boolean(process.env.CRASH_PROCESS); export function maybeCrash(probability: number = 0.5): void { - if (Math.random() < probability) { - console.error("A failure happened!"); + if (Math.random() < probability) { + console.error("A failure happened!"); - if (killProcess) { - console.error("--- CRASHING THE PROCESS ---"); - process.exit(1); - } else { - throw new Error("A failure happened!"); - } + if (killProcess) { + console.error("--- CRASHING THE PROCESS ---"); + process.exit(1); + } else { + throw new Error("A failure happened!"); } + } } -export async function applyUserRole(userId: string, userRole: UserRole): Promise { - maybeCrash(0.3); - console.log(`>>> Applied role ${userRole.roleKey} for user ${userId}`); - return true; +export async function applyUserRole( + userId: string, + userRole: UserRole +): Promise { + maybeCrash(0.3); + console.log(`>>> Applied role ${userRole.roleKey} for user ${userId}`); + return true; } -export async function applyPermission(userId: string, permission: Permission): Promise { - maybeCrash(0.2); - console.log( - `>>> Applied permission ${permission.permissionKey}:${permission.setting} for user ${userId}` - ); -} \ No newline at end of file +export async function applyPermission( + userId: string, + permission: Permission +): Promise { + maybeCrash(0.2); + console.log( + `>>> Applied permission ${permission.permissionKey}:${permission.setting} for user ${userId}` + ); +} diff --git a/code_snippets/ts/src/concepts/utils.ts b/code_snippets/ts/src/concepts/utils.ts index 392df83b..e4bca769 100644 --- a/code_snippets/ts/src/concepts/utils.ts +++ b/code_snippets/ts/src/concepts/utils.ts @@ -1,54 +1,51 @@ import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; +import { ObjectContext } from "@restatedev/restate-sdk"; export enum Status { - NEW = "NEW", - CREATED = "CREATED", - SCHEDULED = "SCHEDULED", - IN_PREPARATION = "IN_PREPARATION", - SCHEDULING_DELIVERY = "SCHEDULING_DELIVERY", - WAITING_FOR_DRIVER = "WAITING_FOR_DRIVER", - IN_DELIVERY = "IN_DELIVERY", - DELIVERED = "DELIVERED", - REJECTED = "REJECTED", - CANCELLED = "CANCELLED", - UNKNOWN = "UNKNOWN" + NEW = "NEW", + CREATED = "CREATED", + SCHEDULED = "SCHEDULED", + IN_PREPARATION = "IN_PREPARATION", + SCHEDULING_DELIVERY = "SCHEDULING_DELIVERY", + WAITING_FOR_DRIVER = "WAITING_FOR_DRIVER", + IN_DELIVERY = "IN_DELIVERY", + DELIVERED = "DELIVERED", + REJECTED = "REJECTED", + CANCELLED = "CANCELLED", + UNKNOWN = "UNKNOWN", } export type Order = { - id: string; - totalCost: number; - deliveryDelay: number; -} + id: string; + totalCost: number; + deliveryDelay: number; +}; export const deliveryManager = restate.object({ - name: "delivery_manager", - handlers: { - startDelivery: async(ctx: ObjectContext, order: Order) => {}, - } + name: "delivery_manager", + handlers: { + startDelivery: async (ctx: ObjectContext, order: Order) => {}, + }, }); - - export class RestaurantClientImpl { - async prepare(id: string, cb: string) { - } + async prepare(id: string, cb: string) {} } export const restaurant = new RestaurantClientImpl(); export class PaymentClient { - async charge(id: string, token: string, amount: number): Promise { - return true; - } + async charge(id: string, token: string, amount: number): Promise { + return true; + } } -export const paymentClnt= new PaymentClient(); +export const paymentClnt = new PaymentClient(); export class EmailClient { - async sendSuccessNotification(emailAddress: string): Promise { - return true; - } + async sendSuccessNotification(emailAddress: string): Promise { + return true; + } } -export const emailClnt = new EmailClient(); \ No newline at end of file +export const emailClnt = new EmailClient(); diff --git a/code_snippets/ts/src/concepts/virtual_objects.ts b/code_snippets/ts/src/concepts/virtual_objects.ts index e914a285..db08efb6 100644 --- a/code_snippets/ts/src/concepts/virtual_objects.ts +++ b/code_snippets/ts/src/concepts/virtual_objects.ts @@ -6,49 +6,49 @@ // import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; +import { ObjectContext } from "@restatedev/restate-sdk"; // export const greeterObject = restate.object({ -// - name: "greeter", - handlers: { - // - // - greet: async (ctx: ObjectContext, greeting: string ) => { - // - // - // - let count = (await ctx.get("count")) ?? 0; - count++; - ctx.set("count", count); - // - // - return `${greeting} ${ctx.key} for the ${count}-th time.`; - // - }, + // + name: "greeter", + handlers: { + // + // + greet: async (ctx: ObjectContext, greeting: string) => { + // + // + // + let count = (await ctx.get("count")) ?? 0; + count++; + ctx.set("count", count); + // + // + return `${greeting} ${ctx.key} for the ${count}-th time.`; + // + }, - // - // - ungreet: async (ctx: ObjectContext) => { - // - // - // - let count = (await ctx.get("count")) ?? 0; - // - if (count > 0) { - // - count--; - // - } - // - ctx.set("count", count); - // - // - return `Dear ${ctx.key}, taking one greeting back: ${count}.`; - // - }, - } + // + // + ungreet: async (ctx: ObjectContext) => { + // + // + // + let count = (await ctx.get("count")) ?? 0; + // + if (count > 0) { + // + count--; + // + } + // + ctx.set("count", count); + // + // + return `Dear ${ctx.key}, taking one greeting back: ${count}.`; + // + }, + }, }); restate.endpoint().bind(greeterObject).listen(); diff --git a/code_snippets/ts/src/concepts/workflow.ts b/code_snippets/ts/src/concepts/workflow.ts index 7bd663c4..314a18db 100644 --- a/code_snippets/ts/src/concepts/workflow.ts +++ b/code_snippets/ts/src/concepts/workflow.ts @@ -10,8 +10,14 @@ */ import * as restate from "@restatedev/restate-sdk"; -import {deliveryManager, emailClnt, Order, paymentClnt, restaurant, Status} from "./utils"; - +import { + deliveryManager, + emailClnt, + Order, + paymentClnt, + restaurant, + Status, +} from "./utils"; /** * Order processing workflow Gets called for each Kafka event that is published to the order topic. @@ -19,61 +25,63 @@ import {deliveryManager, emailClnt, Order, paymentClnt, restaurant, Status} from * the restaurant to start the preparation, and triggers the delivery. */ interface PaymentRequest { - amount: number; - account: string; - email: string; + amount: number; + account: string; + email: string; } interface PaymentSuccess { - account: string; + account: string; } // const payment = restate.workflow({ - name: "payment", - handlers: { - // - run: async (ctx: restate.WorkflowContext, payment: PaymentRequest) => { - - // Validate payment. If not valid, end workflow right here without retries. - if (payment.amount < 0) { - throw new restate.TerminalError("Payment refused: negative amount"); - } - - await ctx.run("make a payment", async () => { - await paymentClnt.charge(ctx.key, payment.account, payment.amount); - }); + name: "payment", + handlers: { + // + run: async (ctx: restate.WorkflowContext, payment: PaymentRequest) => { + // Validate payment. If not valid, end workflow right here without retries. + if (payment.amount < 0) { + throw new restate.TerminalError("Payment refused: negative amount"); + } - // - await ctx.promise("payment.success"); - // - // - ctx.set("status", "Payment succeeded"); - // + await ctx.run("make a payment", async () => { + await paymentClnt.charge(ctx.key, payment.account, payment.amount); + }); - await ctx.run("notify the user", async () => { - await emailClnt.sendSuccessNotification(payment.email); - }); + // + await ctx.promise("payment.success"); + // + // + ctx.set("status", "Payment succeeded"); + // - // - ctx.set("status", "User notified of payment success"); - // + await ctx.run("notify the user", async () => { + await emailClnt.sendSuccessNotification(payment.email); + }); - return "success"; - }, - // + // + ctx.set("status", "User notified of payment success"); + // - // - paymentWebhook: async (ctx: restate.WorkflowSharedContext, account: string) => { - await ctx.promise("payment.success").resolve({ account }); - }, - // + return "success"; + }, + // - // - status: (ctx: restate.WorkflowSharedContext) => ctx.get("status"), - // + // + paymentWebhook: async ( + ctx: restate.WorkflowSharedContext, + account: string + ) => { + await ctx.promise("payment.success").resolve({ account }); }, + // + + // + status: (ctx: restate.WorkflowSharedContext) => ctx.get("status"), + // + }, }); restate.endpoint().bind(payment).listen(); -// \ No newline at end of file +// diff --git a/code_snippets/ts/src/develop/awakeable.ts b/code_snippets/ts/src/develop/awakeable.ts index 74e29a58..f000792a 100644 --- a/code_snippets/ts/src/develop/awakeable.ts +++ b/code_snippets/ts/src/develop/awakeable.ts @@ -1,35 +1,35 @@ import * as restate from "@restatedev/restate-sdk"; const service = restate.service({ - name: "Awakeable", - handlers: { - greet: async (ctx: restate.Context, name: string) => { - // - // - const awakeable = ctx.awakeable(); - const awakeableId = awakeable.id - // + name: "Awakeable", + handlers: { + greet: async (ctx: restate.Context, name: string) => { + // + // + const awakeable = ctx.awakeable(); + const awakeableId = awakeable.id; + // - // - await ctx.run(() => triggerTaskAndDeliverId(awakeableId)); - // + // + await ctx.run(() => triggerTaskAndDeliverId(awakeableId)); + // - // - const payload = await awakeable.promise; - // - // + // + const payload = await awakeable.promise; + // + // - // - ctx.resolveAwakeable(awakeableId, "hello"); - // + // + ctx.resolveAwakeable(awakeableId, "hello"); + // - // - ctx.rejectAwakeable(awakeableId, "my error reason"); - // - }, - } -}) + // + ctx.rejectAwakeable(awakeableId, "my error reason"); + // + }, + }, +}); -function triggerTaskAndDeliverId(awakeableId: string){ - return "123"; -} \ No newline at end of file +function triggerTaskAndDeliverId(awakeableId: string) { + return "123"; +} diff --git a/code_snippets/ts/src/develop/clients/ingress.ts b/code_snippets/ts/src/develop/clients/ingress.ts index ec5c4117..7c3e78c2 100644 --- a/code_snippets/ts/src/develop/clients/ingress.ts +++ b/code_snippets/ts/src/develop/clients/ingress.ts @@ -1,68 +1,74 @@ -import {greetCounterObject, greeterService} from "./utils"; -import {SendOpts} from "@restatedev/restate-sdk-clients"; -import {myWorkflow} from "../../concepts/invocations/utils"; +import { greetCounterObject, greeterService } from "./utils"; +import { SendOpts } from "@restatedev/restate-sdk-clients"; +import { myWorkflow } from "../../concepts/invocations/utils"; import * as clients from "@restatedev/restate-sdk-clients"; const myPlainTSFunction = async () => { - // - // import * as clients from "@restatedev/restate-sdk-clients"; - const rs = clients.connect({url: "http://localhost:8080"}); - const greet = await rs.serviceClient(greeterService) - .greet({greeting: "Hi"}); + // + // import * as clients from "@restatedev/restate-sdk-clients"; + const rs = clients.connect({ url: "http://localhost:8080" }); + const greet = await rs + .serviceClient(greeterService) + .greet({ greeting: "Hi" }); - const count = await rs.objectClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}); - // -} + const count = await rs + .objectClient(greetCounterObject, "Mary") + .greet({ greeting: "Hi" }); + // +}; const myPlainTSFunction2 = async () => { - // - // import * as clients from "@restatedev/restate-sdk-clients"; - const rs = clients.connect({url: "http://localhost:8080"}); - await rs.serviceSendClient(greeterService) - .greet({greeting: "Hi"}); + // + // import * as clients from "@restatedev/restate-sdk-clients"; + const rs = clients.connect({ url: "http://localhost:8080" }); + await rs.serviceSendClient(greeterService).greet({ greeting: "Hi" }); - await rs.objectSendClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}); - // -} + await rs + .objectSendClient(greetCounterObject, "Mary") + .greet({ greeting: "Hi" }); + // +}; const myPlainTSFunction3 = async () => { - // - // import * as clients from "@restatedev/restate-sdk-clients"; - const rs = clients.connect({url: "http://localhost:8080"}); - await rs.serviceSendClient(greeterService) - .greet({greeting: "Hi"}, SendOpts.from({ delay: 1000 })); + // + // import * as clients from "@restatedev/restate-sdk-clients"; + const rs = clients.connect({ url: "http://localhost:8080" }); + await rs + .serviceSendClient(greeterService) + .greet({ greeting: "Hi" }, SendOpts.from({ delay: 1000 })); - await rs.objectSendClient(greetCounterObject, "Mary") - .greet({greeting: "Hi"}, SendOpts.from({ delay: 1000 })); - // -} + await rs + .objectSendClient(greetCounterObject, "Mary") + .greet({ greeting: "Hi" }, SendOpts.from({ delay: 1000 })); + // +}; const servicesIdempotent = async () => { - const request = {greeting: "Hi"} - const rs = clients.connect({url: "http://localhost:8080"}); - // - await rs.serviceSendClient(greeterService) - // withClass highlight-line - .greet(request, SendOpts.from({ idempotencyKey: "abcde" })); - // -} + const request = { greeting: "Hi" }; + const rs = clients.connect({ url: "http://localhost:8080" }); + // + await rs + .serviceSendClient(greeterService) + // withClass highlight-line + .greet(request, SendOpts.from({ idempotencyKey: "abcde" })); + // +}; const servicesAttach = async () => { - const request = {greeting: "Hi"} - // - // import * as clients from "@restatedev/restate-sdk-clients"; - const rs = clients.connect({url: "http://localhost:8080"}); - // Send a message - const handle = await rs.serviceSendClient(greeterService) - // mark - .greet(request, SendOpts.from({ idempotencyKey: "abcde" })); + const request = { greeting: "Hi" }; + // + // import * as clients from "@restatedev/restate-sdk-clients"; + const rs = clients.connect({ url: "http://localhost:8080" }); + // Send a message + const handle = await rs + .serviceSendClient(greeterService) + // mark + .greet(request, SendOpts.from({ idempotencyKey: "abcde" })); - // ... do something else ... + // ... do something else ... - // Attach later to retrieve the result - // mark - const response = await rs.result(handle); - // -} + // Attach later to retrieve the result + // mark + const response = await rs.result(handle); + // +}; diff --git a/code_snippets/ts/src/develop/clients/utils.ts b/code_snippets/ts/src/develop/clients/utils.ts index d5f9bed0..13671512 100644 --- a/code_snippets/ts/src/develop/clients/utils.ts +++ b/code_snippets/ts/src/develop/clients/utils.ts @@ -1,23 +1,25 @@ import * as restate from "@restatedev/restate-sdk"; export const greeterService = restate.service({ - name: "greeterService", - handlers:{ - greet: async (ctx: restate.Context, request: { greeting?: string }) => { - return `Hello ${request.greeting}`; - } - } -}) - + name: "greeterService", + handlers: { + greet: async (ctx: restate.Context, request: { greeting?: string }) => { + return `Hello ${request.greeting}`; + }, + }, +}); export const greetCounterObject = restate.object({ - name: "greetCounterObject", - handlers:{ - greet: async (ctx: restate.ObjectContext, request: { greeting?: string }) => { - let count = (await ctx.get("count")) ?? 0; - count++; - ctx.set("count", count); - return count; - } - } -}) \ No newline at end of file + name: "greetCounterObject", + handlers: { + greet: async ( + ctx: restate.ObjectContext, + request: { greeting?: string } + ) => { + let count = (await ctx.get("count")) ?? 0; + count++; + ctx.set("count", count); + return count; + }, + }, +}); diff --git a/code_snippets/ts/src/develop/durable_timers.ts b/code_snippets/ts/src/develop/durable_timers.ts index bebb71b3..5353972e 100644 --- a/code_snippets/ts/src/develop/durable_timers.ts +++ b/code_snippets/ts/src/develop/durable_timers.ts @@ -1,12 +1,12 @@ import * as restate from "@restatedev/restate-sdk"; const service = restate.service({ - name: "DurableTimers", - handlers: { - greet: async (ctx: restate.Context, name: string) => { - // - await ctx.sleep(10_000); - // - }, - } -}) \ No newline at end of file + name: "DurableTimers", + handlers: { + greet: async (ctx: restate.Context, name: string) => { + // + await ctx.sleep(10_000); + // + }, + }, +}); diff --git a/code_snippets/ts/src/develop/error_handling.ts b/code_snippets/ts/src/develop/error_handling.ts index a3025da0..cc0b1cc3 100644 --- a/code_snippets/ts/src/develop/error_handling.ts +++ b/code_snippets/ts/src/develop/error_handling.ts @@ -2,12 +2,12 @@ import { TerminalError } from "@restatedev/restate-sdk"; import * as restate from "@restatedev/restate-sdk"; const service = restate.service({ - name: "ErrorHandling", - handlers: { - greet: async (ctx: restate.Context, name: string) => { - // - throw new TerminalError("Something went wrong.", { errorCode: 500 }) - // - }, - } -}) + name: "ErrorHandling", + handlers: { + greet: async (ctx: restate.Context, name: string) => { + // + throw new TerminalError("Something went wrong.", { errorCode: 500 }); + // + }, + }, +}); diff --git a/code_snippets/ts/src/develop/journaling_results.ts b/code_snippets/ts/src/develop/journaling_results.ts index 7cdbe342..f0f32e18 100644 --- a/code_snippets/ts/src/develop/journaling_results.ts +++ b/code_snippets/ts/src/develop/journaling_results.ts @@ -1,66 +1,43 @@ import * as restate from "@restatedev/restate-sdk"; -import {CombineablePromise} from "@restatedev/restate-sdk"; -import {MyService} from "./my_service"; +import { CombineablePromise } from "@restatedev/restate-sdk"; +import { MyService } from "./my_service"; const service = restate.service({ - name: "SideEffects", - handlers: { - greet: async (ctx: restate.Context, name: string) => { - // - const result = await ctx.run(async () => doDbRequest()); - // - }, - - promiseCombinators: async (ctx: restate.Context, name: string) => { - // - const sleepPromise = ctx.sleep(100); - const callPromise = ctx - .serviceClient(MyService) - .myHandler("Hi"); - - // - const resultArray = await CombineablePromise - .all([sleepPromise, callPromise]); - // - - // - const anyResult = await CombineablePromise - .any([sleepPromise, callPromise]); - // - - // - const raceResult = await CombineablePromise - .race([sleepPromise, callPromise]); - // - - // - const settledResult = await CombineablePromise - .allSettled([sleepPromise, callPromise]); - // - // - - // - const uuid = ctx.rand.uuidv4(); - // - - // - const randomNumber = ctx.rand.random(); - // - } - } -}) - - -function doDbRequest(){ - return ""; + name: "SideEffects", + handlers: { + greet: async (ctx: restate.Context, name: string) => { + // + const result = await ctx.run(async () => doDbRequest()); + // + }, + + promiseCombinators: async (ctx: restate.Context, name: string) => { + // + const sleepPromise = ctx.sleep(100); + const callPromise = ctx.serviceClient(MyService).myHandler("Hi"); + const resultArray = await CombineablePromise.all([ + sleepPromise, + callPromise, + ]); + // + + // + const uuid = ctx.rand.uuidv4(); + // + + // + const randomNumber = ctx.rand.random(); + // + }, + }, +}); + +function doDbRequest() { + return ""; } const paymentClient = { - call: (txId: string, amt: number) => { - return {error: "", isSuccess: false} - } -} - - - - + call: (txId: string, amt: number) => { + return { error: "", isSuccess: false }; + }, +}; diff --git a/code_snippets/ts/src/develop/kafka.ts b/code_snippets/ts/src/develop/kafka.ts index 59d45dd7..309bc07b 100644 --- a/code_snippets/ts/src/develop/kafka.ts +++ b/code_snippets/ts/src/develop/kafka.ts @@ -1,11 +1,11 @@ import * as restate from "@restatedev/restate-sdk"; const service = restate.object({ - name: "KafkaService", - handlers: { - myEventHandler: async (ctx: restate.Context, name: string) => - // - ctx.request().headers - // - } -}); \ No newline at end of file + name: "KafkaService", + handlers: { + myEventHandler: async (ctx: restate.Context, name: string) => + // + ctx.request().headers, + // + }, +}); diff --git a/code_snippets/ts/src/develop/my_service.ts b/code_snippets/ts/src/develop/my_service.ts index 79c85b03..38199520 100644 --- a/code_snippets/ts/src/develop/my_service.ts +++ b/code_snippets/ts/src/develop/my_service.ts @@ -1,20 +1,17 @@ import * as restate from "@restatedev/restate-sdk"; -import {Context} from "@restatedev/restate-sdk"; +import { Context } from "@restatedev/restate-sdk"; const myService = restate.service({ - name: "MyService", - handlers: { - myHandler: async (ctx: Context, greeting: string) => { - return `${greeting}!`; - }, - } -}) + name: "MyService", + handlers: { + myHandler: async (ctx: Context, greeting: string) => { + return `${greeting}!`; + }, + }, +}); // export const MyService: typeof myService = { name: "MyService" }; // -restate - .endpoint() - .bind(myService) - .listen(); \ No newline at end of file +restate.endpoint().bind(myService).listen(); diff --git a/code_snippets/ts/src/develop/my_virtual_object.ts b/code_snippets/ts/src/develop/my_virtual_object.ts index ef9ca83b..1f3ea3bd 100644 --- a/code_snippets/ts/src/develop/my_virtual_object.ts +++ b/code_snippets/ts/src/develop/my_virtual_object.ts @@ -1,23 +1,26 @@ import * as restate from "@restatedev/restate-sdk"; -import {handlers, ObjectContext, ObjectSharedContext} from "@restatedev/restate-sdk"; +import { + handlers, + ObjectContext, + ObjectSharedContext, +} from "@restatedev/restate-sdk"; const myVirtualObject = restate.object({ - name: "MyVirtualObject", - handlers: { - myHandler: async (ctx: ObjectContext, greeting: string) => { - return `${greeting} ${ctx.key}!`; - }, - myConcurrentHandler: handlers.object.shared( - async (ctx: ObjectSharedContext, greeting: string) => { - return `${greeting} ${ctx.key}!`; - } - ), - } -}) + name: "MyVirtualObject", + handlers: { + myHandler: async (ctx: ObjectContext, greeting: string) => { + return `${greeting} ${ctx.key}!`; + }, + myConcurrentHandler: handlers.object.shared( + async (ctx: ObjectSharedContext, greeting: string) => { + return `${greeting} ${ctx.key}!`; + } + ), + }, +}); -export const MyVirtualObject: typeof myVirtualObject = { name: "MyVirtualObject" }; +export const MyVirtualObject: typeof myVirtualObject = { + name: "MyVirtualObject", +}; -restate - .endpoint() - .bind(myVirtualObject) - .listen(); \ No newline at end of file +restate.endpoint().bind(myVirtualObject).listen(); diff --git a/code_snippets/ts/src/develop/service_communication.ts b/code_snippets/ts/src/develop/service_communication.ts index 5797f6c5..876d80af 100644 --- a/code_snippets/ts/src/develop/service_communication.ts +++ b/code_snippets/ts/src/develop/service_communication.ts @@ -1,57 +1,62 @@ import * as restate from "@restatedev/restate-sdk"; -import {MyService} from "./my_service"; -import {MyVirtualObject} from "./my_virtual_object"; -import {MyWorkflow} from "./workflow"; +import { MyService } from "./my_service"; +import { MyVirtualObject } from "./my_virtual_object"; +import { MyWorkflow } from "./workflow"; const service = restate.service({ - name: "Router", - handlers: { - greet: async (ctx: restate.Context, name: string) => { - // - const response = await ctx.serviceClient(MyService).myHandler("Hi"); - // - }, - greet2: async (ctx: restate.Context, name: string) => { - // - const response = await ctx.objectClient(MyVirtualObject, "Mary").myHandler("Hi"); - // - - // - ctx.serviceSendClient(MyService).myHandler("Hi"); - // - - // - ctx.objectSendClient(MyVirtualObject, "Mary").myHandler("Hi"); - // - - // - ctx.serviceSendClient(MyService, { delay: 5000 }).myHandler("Hi"); - // - - // - ctx.objectSendClient(MyVirtualObject, "Mary", { delay: 5000 }).myHandler("Hi"); - // - - // - ctx.objectSendClient(MyVirtualObject, "Mary").myHandler("I'm call A"); - ctx.objectSendClient(MyVirtualObject, "Mary").myHandler("I'm call B"); - // - }, - callWorkflows: async (ctx: restate.Context, name: string) => { - // - // Call the `run` handler of the workflow (only works once). - await ctx.workflowClient(MyWorkflow, "my-workflow-id").run("Hi"); - // Call some other `interactWithWorkflow` handler of the workflow. - await ctx.workflowClient(MyWorkflow, "my-workflow-id").interactWithWorkflow(); - // - - // - // Call the `run` handler of the workflow (only works once). - ctx.workflowSendClient(MyWorkflow, "wf-id").run("Hi"); - // Call some other `interactWithWorkflow` handler of the workflow. - ctx.workflowSendClient(MyWorkflow, "wf-id").interactWithWorkflow(); - // - - } - } -}) + name: "Router", + handlers: { + greet: async (ctx: restate.Context, name: string) => { + // + const response = await ctx.serviceClient(MyService).myHandler("Hi"); + // + }, + greet2: async (ctx: restate.Context, name: string) => { + // + const response = await ctx + .objectClient(MyVirtualObject, "Mary") + .myHandler("Hi"); + // + + // + ctx.serviceSendClient(MyService).myHandler("Hi"); + // + + // + ctx.objectSendClient(MyVirtualObject, "Mary").myHandler("Hi"); + // + + // + ctx.serviceSendClient(MyService, { delay: 5000 }).myHandler("Hi"); + // + + // + ctx + .objectSendClient(MyVirtualObject, "Mary", { delay: 5000 }) + .myHandler("Hi"); + // + + // + ctx.objectSendClient(MyVirtualObject, "Mary").myHandler("I'm call A"); + ctx.objectSendClient(MyVirtualObject, "Mary").myHandler("I'm call B"); + // + }, + callWorkflows: async (ctx: restate.Context, name: string) => { + // + // Call the `run` handler of the workflow (only works once). + await ctx.workflowClient(MyWorkflow, "my-workflow-id").run("Hi"); + // Call some other `interactWithWorkflow` handler of the workflow. + await ctx + .workflowClient(MyWorkflow, "my-workflow-id") + .interactWithWorkflow(); + // + + // + // Call the `run` handler of the workflow (only works once). + ctx.workflowSendClient(MyWorkflow, "wf-id").run("Hi"); + // Call some other `interactWithWorkflow` handler of the workflow. + ctx.workflowSendClient(MyWorkflow, "wf-id").interactWithWorkflow(); + // + }, + }, +}); diff --git a/code_snippets/ts/src/develop/serving.ts b/code_snippets/ts/src/develop/serving.ts index e9ab5b7b..376fc6b5 100644 --- a/code_snippets/ts/src/develop/serving.ts +++ b/code_snippets/ts/src/develop/serving.ts @@ -2,49 +2,48 @@ import * as restate from "@restatedev/restate-sdk"; import * as http2 from "http2"; const myService = restate.service({ - name: "MyService", - handlers: {} + name: "MyService", + handlers: {}, }); const myVirtualObject = restate.object({ - name: "MyVirtualObject", - handlers: {} + name: "MyVirtualObject", + handlers: {}, }); const myWorkflow = restate.workflow({ - name: "MyWorkflow", - handlers: { run: async () => {}} + name: "MyWorkflow", + handlers: { run: async () => {} }, }); // restate - .endpoint() - .bind(myService) - .bind(myVirtualObject) - .bind(myWorkflow) - .listen(); + .endpoint() + .bind(myService) + .bind(myVirtualObject) + .bind(myWorkflow) + .listen(); // - // const http2Handler = restate - .endpoint() - .bind(myService) - .bind(myVirtualObject) - .bind(myWorkflow) - // withClass highlight-line - .http2Handler() - // withClass highlight-line + .endpoint() + .bind(myService) + .bind(myVirtualObject) + .bind(myWorkflow) + // withClass highlight-line + .http2Handler(); +// withClass highlight-line const httpServer = http2.createServer(http2Handler); httpServer.listen(); // // export const handler = restate - .endpoint() - .bind(myService) - .bind(myVirtualObject) - .bind(myWorkflow) - // withClass highlight-line - .lambdaHandler(); -// \ No newline at end of file + .endpoint() + .bind(myService) + .bind(myVirtualObject) + .bind(myWorkflow) + // withClass highlight-line + .lambdaHandler(); +// diff --git a/code_snippets/ts/src/develop/state.ts b/code_snippets/ts/src/develop/state.ts index a0f2cb6f..11e67a21 100644 --- a/code_snippets/ts/src/develop/state.ts +++ b/code_snippets/ts/src/develop/state.ts @@ -1,29 +1,29 @@ import * as restate from "@restatedev/restate-sdk"; const router = restate.object({ - name: "State", - handlers: { - greet: async (ctx: restate.ObjectContext, name: string) => { - // - const stateKeys = ctx.stateKeys(); - // + name: "State", + handlers: { + greet: async (ctx: restate.ObjectContext, name: string) => { + // + const stateKeys = ctx.stateKeys(); + // - // - const myString = await ctx.get("my-string-key") ?? "my-default"; - const myNumber = await ctx.get("my-number-key") ?? 0; - // + // + const myString = (await ctx.get("my-string-key")) ?? "my-default"; + const myNumber = (await ctx.get("my-number-key")) ?? 0; + // - // - ctx.set("my-key", "my-new-value"); - // + // + ctx.set("my-key", "my-new-value"); + // - // - ctx.clear("my-key"); - // + // + ctx.clear("my-key"); + // - // - ctx.clearAll(); - // - }, - } -}) \ No newline at end of file + // + ctx.clearAll(); + // + }, + }, +}); diff --git a/code_snippets/ts/src/develop/workflow.ts b/code_snippets/ts/src/develop/workflow.ts index d98598b6..becd7620 100644 --- a/code_snippets/ts/src/develop/workflow.ts +++ b/code_snippets/ts/src/develop/workflow.ts @@ -11,28 +11,27 @@ // import * as restate from "@restatedev/restate-sdk"; -import {WorkflowContext, WorkflowSharedContext} from "@restatedev/restate-sdk"; +import { + WorkflowContext, + WorkflowSharedContext, +} from "@restatedev/restate-sdk"; const myWorkflow = restate.workflow({ - name: "MyWorkflow", - handlers: { - run: async (ctx: WorkflowContext, req: string) => { + name: "MyWorkflow", + handlers: { + run: async (ctx: WorkflowContext, req: string) => { + // implement workflow logic here - // implement workflow logic here - - return "success"; - }, + return "success"; + }, - interactWithWorkflow: async (ctx: WorkflowSharedContext) => { - // implement interaction logic here - }, + interactWithWorkflow: async (ctx: WorkflowSharedContext) => { + // implement interaction logic here }, + }, }); export const MyWorkflow: typeof myWorkflow = { name: "MyWorkflow" }; -restate - .endpoint() - .bind(myWorkflow) - .listen(); -// \ No newline at end of file +restate.endpoint().bind(myWorkflow).listen(); +// diff --git a/code_snippets/ts/src/develop/workflows/service.ts b/code_snippets/ts/src/develop/workflows/service.ts index dab99fdd..50e3aa55 100644 --- a/code_snippets/ts/src/develop/workflows/service.ts +++ b/code_snippets/ts/src/develop/workflows/service.ts @@ -1,23 +1,23 @@ import * as restate from "@restatedev/restate-sdk"; -import {SignUpWorkflow} from "./signup"; -import {ObjectContext} from "@restatedev/restate-sdk"; +import { SignUpWorkflow } from "./signup"; +import { ObjectContext } from "@restatedev/restate-sdk"; export default restate.object({ - name: "user-management", - handlers: { - // - signUpUser: async (ctx: ObjectContext, email: string) => { - // focus(1:3) - const result = await ctx - .workflowClient({name: "signup"}, "someone") - .run({email}); - }, - queryStatus: async (ctx: ObjectContext) => { - // focus(1:3) - const status = await ctx - .workflowClient({name: "signup"}, "someone") - .getStatus(); - }, - // - } -}) \ No newline at end of file + name: "user-management", + handlers: { + // + signUpUser: async (ctx: ObjectContext, email: string) => { + // focus(1:3) + const result = await ctx + .workflowClient({ name: "signup" }, "someone") + .run({ email }); + }, + queryStatus: async (ctx: ObjectContext) => { + // focus(1:3) + const status = await ctx + .workflowClient({ name: "signup" }, "someone") + .getStatus(); + }, + // + }, +}); diff --git a/code_snippets/ts/src/develop/workflows/signup.ts b/code_snippets/ts/src/develop/workflows/signup.ts index 07ca5d59..d5fa6d91 100644 --- a/code_snippets/ts/src/develop/workflows/signup.ts +++ b/code_snippets/ts/src/develop/workflows/signup.ts @@ -1,40 +1,45 @@ import userManagement from "./service"; // import * as restate from "@restatedev/restate-sdk"; -import {WorkflowContext} from "@restatedev/restate-sdk"; +import { WorkflowContext } from "@restatedev/restate-sdk"; const signUpWorkflow = restate.workflow({ - name: "signup", - handlers: { - // - run: async (ctx: WorkflowContext, req: { email: string }) => { - const secret = ctx.rand.uuidv4(); - ctx.set("status", "Generated secret"); - - await ctx.run("send email", () => - sendEmailWithLink({ email: req.email, secret })); - ctx.set("status", "Sent email"); - - // - const clickSecret = await ctx.promise("email.clicked"); - // - ctx.set("status", "Clicked email"); - - return clickSecret == secret; - }, - // - - - click: (ctx: restate.WorkflowSharedContext, secret: string) => - // - ctx.promise("email.clicked").resolve(secret), - // - - // - getStatus: (ctx: restate.WorkflowSharedContext) => - ctx.get("status"), - // + name: "signup", + handlers: { + // + run: async (ctx: WorkflowContext, req: { email: string }) => { + const secret = ctx.rand.uuidv4(); + ctx.set("status", "Generated secret"); + + await ctx.run("send email", () => + sendEmailWithLink({ email: req.email, secret }) + ); + ctx.set("status", "Sent email"); + + // + const clickSecret = await ctx + // break + .promise("email.clicked"); + // + ctx.set("status", "Clicked email"); + + return clickSecret == secret; }, + // + + click: (ctx: restate.WorkflowSharedContext, secret: string) => + // + ctx + .promise("email.clicked") + // break + .resolve(secret), + // + + // + getStatus: (ctx: restate.WorkflowSharedContext) => + ctx.get("status"), + // + }, }); export type SignUpWorkflow = typeof signUpWorkflow; @@ -44,7 +49,6 @@ restate.endpoint().bind(signUpWorkflow).listen(); // // -function sendEmailWithLink(param: { email: string, secret: string}){ - console.log(`Sending email to ${param.email} with secret ${param.secret}`); +function sendEmailWithLink(param: { email: string; secret: string }) { + console.log(`Sending email to ${param.email} with secret ${param.secret}`); } - diff --git a/code_snippets/ts/src/develop/workflows/submit.ts b/code_snippets/ts/src/develop/workflows/submit.ts index 9484108d..55e35e65 100644 --- a/code_snippets/ts/src/develop/workflows/submit.ts +++ b/code_snippets/ts/src/develop/workflows/submit.ts @@ -1,39 +1,37 @@ import * as restate from "@restatedev/restate-sdk-clients"; -import {SignUpWorkflow} from "./signup"; -type User = {id: string, email: string}; +import { SignUpWorkflow } from "./signup"; +type User = { id: string; email: string }; +async function signUpUser(user: User) { + // + // import * as restate from "@restatedev/restate-sdk-clients"; + const rs = restate.connect({ url: "http://localhost:8080" }); + const handle = await rs + .workflowClient({ name: "signup" }, "someone") + .workflowSubmit({ email: user.email }); + // -async function signUpUser(user: User){ - // - // import * as restate from "@restatedev/restate-sdk-clients"; - const rs = restate.connect({url: "http://localhost:8080"}); - const handle = await rs - .workflowClient({name: "signup"}, "someone") - .workflowSubmit({email: user.email}); - // + // + const status = await rs + .workflowClient({ name: "signup" }, "someone") + .getStatus(); + // - // - const status = await rs - .workflowClient({name: "signup"}, "someone") - .getStatus(); - // + // + // Option 1: attach and wait for result with handle + const result1 = await rs.result(handle); - // - // Option 1: attach and wait for result with handle - const result1 = await rs.result(handle); - - // Option 2: attach and wait for result with workflow ID - const result2 = await rs - .workflowClient({name: "signup"}, "someone") - .workflowAttach(); - - // Option 3: peek to check if ready with workflow ID - const peekOutput = await rs - .workflowClient({name: "signup"}, "someone") - .workflowOutput(); - if(peekOutput.ready){ - const result3 = peekOutput.result; - } - // + // Option 2: attach and wait for result with workflow ID + const result2 = await rs + .workflowClient({ name: "signup" }, "someone") + .workflowAttach(); + // Option 3: peek to check if ready with workflow ID + const peekOutput = await rs + .workflowClient({ name: "signup" }, "someone") + .workflowOutput(); + if (peekOutput.ready) { + const result3 = peekOutput.result; + } + // } diff --git a/code_snippets/ts/src/get_started/tour.ts b/code_snippets/ts/src/get_started/tour.ts index d49783b7..1afe4d3b 100644 --- a/code_snippets/ts/src/get_started/tour.ts +++ b/code_snippets/ts/src/get_started/tour.ts @@ -1,74 +1,81 @@ import * as restate from "@restatedev/restate-sdk"; const router = restate.service({ - name: "MyService", - handlers: { - greet: async (ctx: restate.Context, name: string) => { - const ticketId = ""; + name: "MyService", + handlers: { + greet: async (ctx: restate.Context, name: string) => { + const ticketId = ""; - // - await ctx.sleep(15 * 60 * 1000); - // + // + await ctx.sleep(15 * 60 * 1000); + // - // - await ctx.sleep(15 * 60 * 1000); - ctx.objectSendClient(TicketObject, ticketId).unreserve(); - // - }, - } -}) + // + await ctx.sleep(15 * 60 * 1000); + ctx.objectSendClient(TicketObject, ticketId).unreserve(); + // + }, + }, +}); const checkoutService = restate.service({ - name: "MyService", - handlers: { - // - async handle(ctx: restate.Context, request: { userId: string; tickets: string[] }) { - // withClass(1:3) highlight-line - const idempotencyKey = ctx.rand.uuidv4(); - console.info("My idempotency key: " + idempotencyKey); - throw new Error("Something happened!"); + name: "MyService", + handlers: { + // + async handle( + ctx: restate.Context, + request: { userId: string; tickets: string[] } + ) { + // withClass(1:3) highlight-line + const idempotencyKey = ctx.rand.uuidv4(); + console.info("My idempotency key: " + idempotencyKey); + throw new Error("Something happened!"); - return true; - }, - // - } -}) + return true; + }, + // + }, +}); const secondCheckoutService = restate.service({ - name: "MyService", - handlers: { - // - async handle(ctx: restate.Context, request: { userId: string; tickets: string[] }) { - // withClass highlight-line - const totalPrice = request.tickets.length * 40; + name: "MyService", + handlers: { + // + async handle( + ctx: restate.Context, + request: { userId: string; tickets: string[] } + ) { + // withClass highlight-line + const totalPrice = request.tickets.length * 40; - const idempotencyKey = ctx.rand.uuidv4(); - // withClass highlight-line - const success = await ctx.run(() => PaymentClient.get().call(idempotencyKey, totalPrice)); + const idempotencyKey = ctx.rand.uuidv4(); + // withClass highlight-line + const success = await ctx.run(() => + PaymentClient.get().call(idempotencyKey, totalPrice) + ); - return success; - }, - // - } -}) + return success; + }, + // + }, +}); export const ticketObject = restate.object({ - name: "TicketObject", - handlers: { - async unreserve(ctx: restate.ObjectContext) { - return true; - }, - } + name: "TicketObject", + handlers: { + async unreserve(ctx: restate.ObjectContext) { + return true; + }, + }, }); const TicketObject: typeof ticketObject = { name: "TicketObject" }; - class PaymentClient { - static get() { - return new PaymentClient(); - } + static get() { + return new PaymentClient(); + } - async call(idempotencyKey: string, totalPrice: number) { - return true; - } + async call(idempotencyKey: string, totalPrice: number) { + return true; + } } diff --git a/code_snippets/ts/src/operate/monitoring.ts b/code_snippets/ts/src/operate/monitoring.ts index 1e155c05..6d1c859f 100644 --- a/code_snippets/ts/src/operate/monitoring.ts +++ b/code_snippets/ts/src/operate/monitoring.ts @@ -1,14 +1,14 @@ import * as restate from "@restatedev/restate-sdk"; const service = restate.object({ - name: "Greeter", - handlers: { - greet: async (ctx: restate.ObjectContext, name: string) => { - // - ctx.console.info("This will not be printed again during replays"); - ctx.console.debug("This will not be printed again during replays"); - // Any other console logging method can be used - // - } - } -}) \ No newline at end of file + name: "Greeter", + handlers: { + greet: async (ctx: restate.ObjectContext, name: string) => { + // + ctx.console.info("This will not be printed again during replays"); + ctx.console.debug("This will not be printed again during replays"); + // Any other console logging method can be used + // + }, + }, +}); diff --git a/code_snippets/ts/src/use_cases/async_tasks/fan_out_worker.ts b/code_snippets/ts/src/use_cases/async_tasks/fan_out_worker.ts index b674cd10..f10f6453 100644 --- a/code_snippets/ts/src/use_cases/async_tasks/fan_out_worker.ts +++ b/code_snippets/ts/src/use_cases/async_tasks/fan_out_worker.ts @@ -3,33 +3,35 @@ import { Context, CombineablePromise } from "@restatedev/restate-sdk"; // const workerService = restate.service({ - name: "worker", - handlers: { - run: async (ctx: Context, task: Task) => { - // Split the task in subtasks - const subtasks: SubTask[] = await ctx.run("split task", - () => split(task)); - - const resultPromises = []; - // - for (const subtask of subtasks) { - const subResultPromise = ctx.serviceClient(workerService) - .runSubtask(subtask); - // - resultPromises.push(subResultPromise); - } - - // - const results = await CombineablePromise.all(resultPromises); - // - return aggregate(results); - }, - - runSubtask: async (ctx: Context, subtask: SubTask) => { - // Processing logic goes here ... - // Can be moved to a separate service to scale independently - } - } + name: "worker", + handlers: { + run: async (ctx: Context, task: Task) => { + // Split the task in subtasks + const subtasks: SubTask[] = await ctx.run("split task", () => + split(task) + ); + + const resultPromises = []; + // + for (const subtask of subtasks) { + const subResultPromise = ctx + .serviceClient(workerService) + .runSubtask(subtask); + // + resultPromises.push(subResultPromise); + } + + // + const results = await CombineablePromise.all(resultPromises); + // + return aggregate(results); + }, + + runSubtask: async (ctx: Context, subtask: SubTask) => { + // Processing logic goes here ... + // Can be moved to a separate service to scale independently + }, + }, }); // @@ -39,16 +41,16 @@ export const handler = restate.endpoint().bind(workerService).lambdaHandler(); // ----------------------- Stubs to please the compiler ----------------------- -type Task = {} -type Result = {} +type Task = {}; +type Result = {}; -type SubTask = { } -type SubTaskResult = void +type SubTask = {}; +type SubTaskResult = void; async function split(task: Task): Promise { - return []; + return []; } async function aggregate(packages: SubTaskResult[]): Promise { - return {}; -} \ No newline at end of file + return {}; +} diff --git a/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/async_task_service.ts b/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/async_task_service.ts index 0db901a6..eb403e63 100644 --- a/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/async_task_service.ts +++ b/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/async_task_service.ts @@ -1,18 +1,18 @@ // --------------- define async task logic as a service handler --------------- import * as restate from "@restatedev/restate-sdk"; -import {Context} from "@restatedev/restate-sdk"; +import { Context } from "@restatedev/restate-sdk"; // const asyncTaskService = restate.service({ - name: "taskWorker", - handlers: { - // - runTask: async (ctx: Context, params: TaskOpts) => { - return someHeavyWork(params); - } - // - } + name: "taskWorker", + handlers: { + // + runTask: async (ctx: Context, params: TaskOpts) => { + return someHeavyWork(params); + }, + // + }, }); export type AsyncTaskService = typeof asyncTaskService; @@ -22,6 +22,8 @@ const endpoint = restate.endpoint().bind(asyncTaskService).listen(9080); // ----------------------- Stubs to please the compiler ----------------------- -export type TaskOpts = {} +export type TaskOpts = {}; -function someHeavyWork(work: TaskOpts) { return "Work!"} \ No newline at end of file +function someHeavyWork(work: TaskOpts) { + return "Work!"; +} diff --git a/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/task_submitter.ts b/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/task_submitter.ts index e9678643..0c03cf90 100644 --- a/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/task_submitter.ts +++ b/code_snippets/ts/src/use_cases/async_tasks/simple_async_task/task_submitter.ts @@ -1,6 +1,6 @@ import * as restate from "@restatedev/restate-sdk-clients"; import { SendOpts } from "@restatedev/restate-sdk-clients"; -import {AsyncTaskService, TaskOpts} from "./async_task_service"; +import { AsyncTaskService, TaskOpts } from "./async_task_service"; /* * Restate is as a sophisticated task queue, with extra features like @@ -18,29 +18,29 @@ const RESTATE_URL = process.env.RESTATE_URL ?? "http://localhost:8080"; // async function submitAndAwaitTask(task: TaskOpts) { - const rs = restate.connect({ url: RESTATE_URL }); + const rs = restate.connect({ url: RESTATE_URL }); - // - const taskHandle = await rs - .serviceSendClient({ name: "taskWorker" }) - .runTask( - task, - // - SendOpts.from({ idempotencyKey: "dQw4w9WgXcQ" }) - // - ); - // + // + const taskHandle = await rs + .serviceSendClient({ name: "taskWorker" }) + .runTask( + task, + // + SendOpts.from({ idempotencyKey: "dQw4w9WgXcQ" }) + // + ); + // - // await the handler's result - // - const result = await rs.result(taskHandle); - // + // await the handler's result + // + const result = await rs.result(taskHandle); + // } // async function attachToTask(taskHandle: string) { - const rs = restate.connect({ url: RESTATE_URL }); - const result2 = await rs.result(JSON.parse(taskHandle)); + const rs = restate.connect({ url: RESTATE_URL }); + const result2 = await rs.result(JSON.parse(taskHandle)); } // -// \ No newline at end of file +// diff --git a/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/client.ts b/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/client.ts index 2690c858..191e1751 100644 --- a/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/client.ts +++ b/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/client.ts @@ -1,6 +1,6 @@ import * as restate from "@restatedev/restate-sdk-clients"; import * as readline from "readline"; -import {DataPrepService} from "./data_preparation_service"; +import { DataPrepService } from "./data_preparation_service"; const RESTATE_URL = process.env.RESTATE_URL ?? "http://localhost:8080"; // Client: @@ -14,42 +14,48 @@ const rs = restate.connect({ url: RESTATE_URL }); const dataPrepService: DataPrepService = { name: "dataPrep" }; async function downloadData(userId: string) { - // - const dataPrep = rs.workflowClient(dataPrepService, userId); - // - - // - await dataPrep.workflowSubmit({ userId }); - // - - // - const result = await withTimeout(dataPrep.workflowAttach(), 30_000); - // - - // - if (result === Timeout) { - const email = await readLine("This takes long... Mail us the link later"); - await dataPrep.resultAsEmail({ email }); - return; - } - // - // ... process directly ... + // + const dataPrep = rs.workflowClient(dataPrepService, userId); + // + + // + await dataPrep.workflowSubmit({ userId }); + // + + // + const result = await withTimeout(dataPrep.workflowAttach(), 30_000); + // + + // + if (result === Timeout) { + const email = await readLine("This takes long... Mail us the link later"); + await dataPrep.resultAsEmail({ email }); + return; + } + // + // ... process directly ... } // -const Timeout = Symbol("Timeout") +const Timeout = Symbol("Timeout"); -function withTimeout(promise: Promise, millis: number): Promise { - const timeoutPromise = new Promise((resolve) => setTimeout(resolve, millis, Timeout)); - return Promise.race([promise, timeoutPromise]); +function withTimeout( + promise: Promise, + millis: number +): Promise { + const timeoutPromise = new Promise((resolve) => + setTimeout(resolve, millis, Timeout) + ); + return Promise.race([promise, timeoutPromise]); } async function readLine(prompt: string): Promise { - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout - }); - - return new Promise(resolve => rl.question(prompt, resolve)).finally(() => rl.close()); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + + return new Promise((resolve) => rl.question(prompt, resolve)).finally( + () => rl.close() + ); } - diff --git a/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/data_preparation_service.ts b/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/data_preparation_service.ts index 9648ee4d..8ac18af0 100644 --- a/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/data_preparation_service.ts +++ b/code_snippets/ts/src/use_cases/async_tasks/sync_to_async/data_preparation_service.ts @@ -1,46 +1,54 @@ import * as restate from "@restatedev/restate-sdk"; -import {WorkflowContext, WorkflowSharedContext} from "@restatedev/restate-sdk"; +import { + WorkflowContext, + WorkflowSharedContext, +} from "@restatedev/restate-sdk"; // const dataPreparationService = restate.workflow({ - name: "dataPrep", - handlers: { - run: async (ctx: WorkflowContext, args: { userId: string }) => { - // - const url = await ctx.run("create S3 bucket", () => createS3Bucket()); - await ctx.run("upload data", () => uploadData(url)); - - // - await ctx.promise("url").resolve(url); - // - - return url; - // - }, - - resultAsEmail: async (ctx: WorkflowSharedContext, req: { email: string }) => { - // - const url = await ctx.promise("url"); - // - await ctx.run("send email", () => sendEmail(url, req.email )); - } - } + name: "dataPrep", + handlers: { + run: async (ctx: WorkflowContext, args: { userId: string }) => { + // + const url = await ctx.run("create S3 bucket", () => createS3Bucket()); + await ctx.run("upload data", () => uploadData(url)); + + // + await ctx.promise("url").resolve(url); + // + + return url; + // + }, + + resultAsEmail: async ( + ctx: WorkflowSharedContext, + req: { email: string } + ) => { + // + const url = await ctx.promise("url"); + // + await ctx.run("send email", () => sendEmail(url, req.email)); + }, + }, }); export type DataPrepService = typeof dataPreparationService; // async function createS3Bucket(): Promise { - const bucket = Number(Math.random() * 1_000_000_000).toString(16); - return new URL(`https://s3-eu-central-1.amazonaws.com/${bucket}/`); + const bucket = Number(Math.random() * 1_000_000_000).toString(16); + return new URL(`https://s3-eu-central-1.amazonaws.com/${bucket}/`); } async function uploadData(target: URL) { - // simulate some work by delaying for a while. sometimes takes really long. - return new Promise((resolve) => setTimeout(resolve, Math.random() < 0.0 ? 1_500 : 10_000)); + // simulate some work by delaying for a while. sometimes takes really long. + return new Promise((resolve) => + setTimeout(resolve, Math.random() < 0.0 ? 1_500 : 10_000) + ); } async function sendEmail(url: URL, email: string) { - // send email - console.log(` >>> Sending email to '${email}' with URL ${url}`); -} \ No newline at end of file + // send email + console.log(` >>> Sending email to '${email}' with URL ${url}`); +} diff --git a/code_snippets/ts/src/use_cases/event_processing.ts b/code_snippets/ts/src/use_cases/event_processing.ts index 5079ad16..cd7fe17c 100644 --- a/code_snippets/ts/src/use_cases/event_processing.ts +++ b/code_snippets/ts/src/use_cases/event_processing.ts @@ -2,63 +2,69 @@ import * as restate from "@restatedev/restate-sdk"; // const userUpdates = restate.object({ - name: "userUpdates", - handlers: { - // - updateUserEvent: async (ctx: restate.ObjectContext, event: UserUpdate) => { - // - const { profile, permissions, resources } = verifyEvent(event); + name: "userUpdates", + handlers: { + // + updateUserEvent: async (ctx: restate.ObjectContext, event: UserUpdate) => { + // + const { profile, permissions, resources } = verifyEvent(event); - // - let userId = await ctx.run(() => updateProfile(profile)); - // - // - while (userId === NOT_READY) { - // - await ctx.sleep(5_000); - // - // - userId = await ctx.run(() => updateProfile(profile)); - // - } + // + let userId = await ctx.run(() => updateProfile(profile)); + // + // + while (userId === NOT_READY) { + // + await ctx.sleep(5_000); + // + // + userId = await ctx.run(() => updateProfile(profile)); + // + } - // - const roleId = await ctx.run(() => setPermissions(userId, permissions)); - await ctx.run(() => provisionResources(userId, roleId, resources)); - // - // - }, + // + const roleId = await ctx.run(() => setPermissions(userId, permissions)); + await ctx.run(() => provisionResources(userId, roleId, resources)); + // + // }, + }, }); // - import { TerminalError } from "@restatedev/restate-sdk"; export type UserUpdate = { - profile: string; - permissions: string; - resources: string; + profile: string; + permissions: string; + resources: string; }; export const NOT_READY = "NOT_READY"; -export async function updateProfile(profile: string, token?: string): Promise { - return Math.random() < 0.8 ? NOT_READY : profile + "-id"; +export async function updateProfile( + profile: string, + token?: string +): Promise { + return Math.random() < 0.8 ? NOT_READY : profile + "-id"; } export async function setPermissions( - id: string, - permissions: string, - token?: string + id: string, + permissions: string, + token?: string ): Promise { - return permissions; + return permissions; } -export async function provisionResources(user: string, role: string, resources: string) {} +export async function provisionResources( + user: string, + role: string, + resources: string +) {} export function verifyEvent(request: UserUpdate): UserUpdate { - if (request?.profile && request?.permissions && request?.resources) { - return request; - } else { - throw new TerminalError("Incomplete event"); - } -} \ No newline at end of file + if (request?.profile && request?.permissions && request?.resources) { + return request; + } else { + throw new TerminalError("Incomplete event"); + } +} diff --git a/code_snippets/ts/src/use_cases/events_state.ts b/code_snippets/ts/src/use_cases/events_state.ts index b26acf48..b7a06df6 100644 --- a/code_snippets/ts/src/use_cases/events_state.ts +++ b/code_snippets/ts/src/use_cases/events_state.ts @@ -10,56 +10,55 @@ */ import * as restate from "@restatedev/restate-sdk"; -import {ObjectContext} from "@restatedev/restate-sdk"; +import { ObjectContext } from "@restatedev/restate-sdk"; // const eventEnricher = restate.object({ - name: "profile", - handlers: { - // - userEvent: async (ctx: ObjectContext, event: UserProfile) => { - // - // - ctx.set("user", event); - // - // - ctx.objectSendClient(EventEnricher, ctx.key,{ delay: 1000 }).emit(); - // - }, + name: "profile", + handlers: { + // + userEvent: async (ctx: ObjectContext, event: UserProfile) => { + // + // + ctx.set("user", event); + // + // + ctx.objectSendClient(EventEnricher, ctx.key, { delay: 1000 }).emit(); + // + }, - // - featureEvent: async (ctx: ObjectContext, featureEvent: string) => { - // - // - const userEvent = await ctx.get("user"); - // - (userEvent!.features ??= []).push(featureEvent); - // - ctx.set("user", userEvent) - // - }, + // + featureEvent: async (ctx: ObjectContext, featureEvent: string) => { + // + // + const userEvent = await ctx.get("user"); + // + (userEvent!.features ??= []).push(featureEvent); + // + ctx.set("user", userEvent); + // + }, - // - emit: async (ctx: ObjectContext) => { - // - // - send(ctx.key, await ctx.get("user")); - ctx.clearAll(); - // - } - } -}) + // + emit: async (ctx: ObjectContext) => { + // + // + send(ctx.key, await ctx.get("user")); + ctx.clearAll(); + // + }, + }, +}); type EventEnricherType = typeof eventEnricher; -const EventEnricher: EventEnricherType = {name:"profile"} +const EventEnricher: EventEnricherType = { name: "profile" }; // type UserProfile = { - id: string; - name: string; - email: string; - features: string[]; + id: string; + name: string; + email: string; + features: string[]; }; -function send(key: string, user: UserProfile | null) { -} \ No newline at end of file +function send(key: string, user: UserProfile | null) {} diff --git a/code_snippets/ts/src/use_cases/idempotency.ts b/code_snippets/ts/src/use_cases/idempotency.ts index 5d0c8f20..058f4c42 100644 --- a/code_snippets/ts/src/use_cases/idempotency.ts +++ b/code_snippets/ts/src/use_cases/idempotency.ts @@ -1,27 +1,26 @@ import * as restate from "@restatedev/restate-sdk-clients"; import { Opts } from "@restatedev/restate-sdk-clients"; -import express from 'express'; -import {ProductService} from "./idempotency_utils"; +import express from "express"; +import { ProductService } from "./idempotency_utils"; -const app = express() +const app = express(); process.env.RESTATE_URL = "localhost:8080"; // const rs = restate.connect({ url: process.env.RESTATE_URL }); -const productService: ProductService = {name: "product"}; +const productService: ProductService = { name: "product" }; -app.get('/reserve/:product/:reservationId', async (req, res) => { - const { product, reservationId } = req.params; +app.get("/reserve/:product/:reservationId", async (req, res) => { + const { product, reservationId } = req.params; - // withClass(1:5) highlight-line - const products = rs.serviceClient(productService); - const reservation = await products.reserve( - product, - Opts.from({ idempotencyKey : reservationId }) - ); + // withClass(1:5) highlight-line + const products = rs.serviceClient(productService); + const reservation = await products.reserve( + product, + Opts.from({ idempotencyKey: reservationId }) + ); - res.json(reservation); -}) + res.json(reservation); +}); // - diff --git a/code_snippets/ts/src/use_cases/idempotency_utils.ts b/code_snippets/ts/src/use_cases/idempotency_utils.ts index b803613b..5a8f5b6b 100644 --- a/code_snippets/ts/src/use_cases/idempotency_utils.ts +++ b/code_snippets/ts/src/use_cases/idempotency_utils.ts @@ -1,11 +1,11 @@ import * as restate from "@restatedev/restate-sdk"; -import {Context} from "@restatedev/restate-sdk"; +import { Context } from "@restatedev/restate-sdk"; const productService = restate.service({ - name: "product", - handlers: { - reserve: async (ctx: Context, product: string) => {} - } + name: "product", + handlers: { + reserve: async (ctx: Context, product: string) => {}, + }, }); -export type ProductService = typeof productService; \ No newline at end of file +export type ProductService = typeof productService; diff --git a/code_snippets/ts/src/use_cases/role_updater.ts b/code_snippets/ts/src/use_cases/role_updater.ts index 5db68a51..a499170c 100644 --- a/code_snippets/ts/src/use_cases/role_updater.ts +++ b/code_snippets/ts/src/use_cases/role_updater.ts @@ -10,92 +10,95 @@ */ import * as restate from "@restatedev/restate-sdk"; -import {Context} from "@restatedev/restate-sdk"; +import { Context } from "@restatedev/restate-sdk"; // // const roleUpdater = restate.object({ - // - name: "roleUpdate", - handlers: { - // - // - update: async function (ctx: Context, update: UpdateRequest) { - // - // - const { userId, role, permissions: permissions } = update; + // + name: "roleUpdate", + handlers: { + // + // + update: async function (ctx: Context, update: UpdateRequest) { + // + // + const { userId, role, permissions: permissions } = update; - // - const previousRole = await ctx.run(() => getCurrentRole(userId)); - await ctx.run(() => applyUserRole(userId, role)); - // + // + const previousRole = await ctx.run(() => getCurrentRole(userId)); + await ctx.run(() => applyUserRole(userId, role)); + // - const previousPermissions: Permission[] = []; - for (const permission of permissions) { - // - try { - // - const previous = await ctx.run(() => - applyPermission(userId, permission)); - // - previousPermissions.push(previous); - } catch (err) { - if (err instanceof restate.TerminalError) { - await rollback(ctx, userId, previousRole, previousPermissions); - } - throw err; - } - // - } + const previousPermissions: Permission[] = []; + for (const permission of permissions) { + // + try { + // + const previous = await ctx.run(() => + applyPermission(userId, permission) + ); + // + previousPermissions.push(previous); + } catch (err) { + if (err instanceof restate.TerminalError) { + await rollback(ctx, userId, previousRole, previousPermissions); + } + throw err; } + // + } }, -}) + }, +}); // async function rollback( - ctx: restate.Context, - userId: string, - role: UserRole, - permissions: Permission[] + ctx: restate.Context, + userId: string, + role: UserRole, + permissions: Permission[] ) { - console.log(">>> !!! ROLLING BACK CHANGES !!! <<<"); - for (const prev of permissions.reverse()) { - await ctx.run(() => applyPermission(userId, prev)); - } - await ctx.run(() => applyUserRole(userId, role)); + console.log(">>> !!! ROLLING BACK CHANGES !!! <<<"); + for (const prev of permissions.reverse()) { + await ctx.run(() => applyPermission(userId, prev)); + } + await ctx.run(() => applyUserRole(userId, role)); } export type UserRole = { - roleKey: string; - roleDescription: string; + roleKey: string; + roleDescription: string; }; export type Permission = { - permissionKey: string; - setting: string; + permissionKey: string; + setting: string; }; export type UpdateRequest = { - userId: string; - role: UserRole; - permissions: Permission[]; + userId: string; + role: UserRole; + permissions: Permission[]; }; export async function getCurrentRole(userId: string): Promise { - // in this example, the previous role was always just 'viewer' - return { roleKey: "viewer", roleDescription: "User that cannot do much" }; + // in this example, the previous role was always just 'viewer' + return { roleKey: "viewer", roleDescription: "User that cannot do much" }; } -export async function applyUserRole(userId: string, userRole: UserRole): Promise { - console.log(`>>> Applied role ${userRole.roleKey} for user ${userId}`); - return true; - +export async function applyUserRole( + userId: string, + userRole: UserRole +): Promise { + console.log(`>>> Applied role ${userRole.roleKey} for user ${userId}`); + return true; } export async function applyPermission( - userId: string, - permission: Permission + userId: string, + permission: Permission ): Promise { - const { permissionKey, setting } = permission; - return { permissionKey, setting: "blocked" }; -} \ No newline at end of file + const { permissionKey, setting } = permission; + return { permissionKey, setting: "blocked" }; +} diff --git a/code_snippets/ts/src/use_cases/signup_workflow.ts b/code_snippets/ts/src/use_cases/signup_workflow.ts index 1c6b8a96..c974618a 100644 --- a/code_snippets/ts/src/use_cases/signup_workflow.ts +++ b/code_snippets/ts/src/use_cases/signup_workflow.ts @@ -1,71 +1,81 @@ import * as restate from "@restatedev/restate-sdk"; -import {TerminalError, WorkflowContext, WorkflowSharedContext} from "@restatedev/restate-sdk"; +import { + TerminalError, + WorkflowContext, + WorkflowSharedContext, +} from "@restatedev/restate-sdk"; // // const signUpWorkflow = restate.workflow({ - name: "sign-up-workflow", - handlers: { - run: async (ctx: WorkflowContext, user: User) => { - // - const { id, name, email } = user; + name: "sign-up-workflow", + handlers: { + run: async (ctx: WorkflowContext, user: User) => { + // + const { id, name, email } = user; - // - ctx.set("stage", "Creating User"); - // - // - await ctx.run(() => createUserEntry({ id, name })); - // + // + ctx.set("stage", "Creating User"); + // + // + await ctx.run(() => createUserEntry({ id, name })); + // - // - ctx.set("stage", "Email Verification"); - // - // - const secret = ctx.rand.uuidv4(); - await ctx.run(() => sendEmailWithLink({ email, secret })); - // + // + ctx.set("stage", "Email Verification"); + // + // + const secret = ctx.rand.uuidv4(); + await ctx.run(() => sendEmailWithLink({ email, secret })); + // - // - const clickSecret = await ctx.promise("email-link"); - // - // - if (clickSecret !== secret) { - // - ctx.set("stage", `Verification failed`); - // - throw new TerminalError("Wrong secret from email link"); - } - // - ctx.set("stage", "User verified"); - // - return true; - // - }, + // + const clickSecret = await ctx.promise("email-link"); + // + // + if (clickSecret !== secret) { + // + ctx.set("stage", `Verification failed`); + // + throw new TerminalError("Wrong secret from email link"); + } + // + ctx.set("stage", "User verified"); + // + return true; + // + }, - // - getStage: (ctx: WorkflowSharedContext) => ctx.get("stage"), - // + // + getStage: (ctx: WorkflowSharedContext) => ctx.get("stage"), + // - // - approveEmail: (ctx: WorkflowSharedContext, secret: string) => - ctx.promise("email-link").resolve(secret), + // + approveEmail: (ctx: WorkflowSharedContext, secret: string) => + ctx.promise("email-link").resolve(secret), - rejectEmail: (ctx: WorkflowSharedContext) => - ctx.promise("email-link").reject("Abort verification"), - // - } + rejectEmail: (ctx: WorkflowSharedContext) => + ctx.promise("email-link").reject("Abort verification"), + // + }, }); // export type SignUpWorkflow = typeof signUpWorkflow; -type KafkaEvent = { topic: string, message: string }; -export type User = { id: string, name: string, email: string }; +type KafkaEvent = { topic: string; message: string }; +export type User = { id: string; name: string; email: string }; -function sendEmailWithLink({ email, secret }: { email: string; secret: string }) { - // send email with link +function sendEmailWithLink({ + email, + secret, +}: { + email: string; + secret: string; +}) { + // send email with link } function createUserEntry({ id, name }: { id: string; name: string }) { - // create user entry -} \ No newline at end of file + // create user entry +} diff --git a/code_snippets/ts/src/use_cases/submit.ts b/code_snippets/ts/src/use_cases/submit.ts index 27b1cd69..6ae891ec 100644 --- a/code_snippets/ts/src/use_cases/submit.ts +++ b/code_snippets/ts/src/use_cases/submit.ts @@ -1,21 +1,25 @@ import * as clients from "@restatedev/restate-sdk-clients"; -import {SignUpWorkflow, User} from "./signup_workflow"; +import { SignUpWorkflow, User } from "./signup_workflow"; -async function submit(user: User){ -// - // import * as clients from "@restatedev/restate-sdk-clients"; - const rs = clients.connect({url: "http://localhost:8080"}); +async function submit(user: User) { + // + // import * as clients from "@restatedev/restate-sdk-clients"; + const rs = clients.connect({ url: "http://localhost:8080" }); + // mark + await rs // mark - await rs.workflowClient({name: "sign-up-workflow"}, user.id) - // mark - .workflowSubmit(user); + .workflowClient({ name: "sign-up-workflow" }, user.id) + // mark + .workflowSubmit(user); - // do something else, with workflow running in the background + // do something else, with workflow running in the background - // attach back to the workflow + // attach back to the workflow + // mark + const result = await rs + // mark + .workflowClient({ name: "sign-up-workflow" }, user.id) // mark - const result = await rs.workflowClient({name: "sign-up-workflow"}, user.id) - // mark - .workflowAttach(); -// + .workflowAttach(); + // } diff --git a/code_snippets/ts/tsconfig.json b/code_snippets/ts/tsconfig.json index c3473680..a63f955c 100644 --- a/code_snippets/ts/tsconfig.json +++ b/code_snippets/ts/tsconfig.json @@ -11,8 +11,10 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "esnext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - "lib": ["esnext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "target": "esnext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "lib": [ + "esnext" + ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ @@ -25,7 +27,7 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ + "module": "commonjs" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ @@ -44,15 +46,15 @@ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ - "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + "allowJs": true /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */, // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - "declarationMap": true, /* Create sourcemaps for d.ts files. */ - "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - "outDir": "./dist", /* Specify an output folder for all emitted files. */ + "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, + "declarationMap": true /* Create sourcemaps for d.ts files. */, + "sourceMap": true /* Create source map files for emitted JavaScript files. */, + "outDir": "./dist" /* Specify an output folder for all emitted files. */, // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ @@ -74,15 +76,15 @@ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ /* Interop Constraints */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -103,8 +105,8 @@ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ - "skipLibCheck": true, /* Skip type checking all .d.ts files. */ - "skipDefaultLibCheck": true /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */, + "skipDefaultLibCheck": true /* Skip type checking .d.ts files that are included with TypeScript. */ }, "include": ["src/"] } diff --git a/docs/concepts/durable_building_blocks.mdx b/docs/concepts/durable_building_blocks.mdx index d8e94cb5..f366e54d 100644 --- a/docs/concepts/durable_building_blocks.mdx +++ b/docs/concepts/durable_building_blocks.mdx @@ -35,7 +35,7 @@ Let's have a look at a handler that processes food orders: ```ts order_processor.ts - CODE_LOAD::ts/src/concepts/food_ordering_functions.ts + CODE_LOAD::ts/src/concepts/food_ordering.ts?1 ``` --- @@ -45,7 +45,7 @@ Let's have a look at a handler that processes food orders: When a failure happens, Restate handles retries and recovers partial progress. ```ts order_processor.ts - CODE_LOAD::ts/src/concepts/food_ordering_rpc.ts + CODE_LOAD::ts/src/concepts/food_ordering.ts?2 ``` --- @@ -56,7 +56,7 @@ Let's have a look at a handler that processes food orders: A great match for function-as-a-service platforms. ```ts order_processor.ts - CODE_LOAD::ts/src/concepts/food_ordering_awakeables.ts + CODE_LOAD::ts/src/concepts/food_ordering.ts?3 ``` --- @@ -66,7 +66,7 @@ Let's have a look at a handler that processes food orders: ```ts order_processor.ts - CODE_LOAD::ts/src/concepts/food_ordering_state.ts + CODE_LOAD::ts/src/concepts/food_ordering.ts?4 ``` --- @@ -74,7 +74,7 @@ Let's have a look at a handler that processes food orders: Store the result of an action in Restate. The result gets replayed in case of failures and the action is not executed again. ```ts order_processor.ts - CODE_LOAD::ts/src/concepts/food_ordering_side_effect.ts + CODE_LOAD::ts/src/concepts/food_ordering.ts?5 ``` diff --git a/docs/concepts/invocations.mdx b/docs/concepts/invocations.mdx index 9056ddb5..67ff6eee 100644 --- a/docs/concepts/invocations.mdx +++ b/docs/concepts/invocations.mdx @@ -4,12 +4,9 @@ description: "" --- import CliAnimation from "../../src/components/CliAnimation"; -import FeatureWidget from "../../src/components/FeatureWidget"; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -import ExampleWidget from "../../src/components/ExampleWidget" import FeatureList from "../../src/components/FeatureList" -import SpotlightCard from "../../src/components/SpotlightCard" # Invocations @@ -61,16 +58,18 @@ Invocations get a unique identifier. This identifier is used to track the progre - + - **Request-response invocations** allow you to wait on a response from the handler. + **Request-response invocations** allow you to wait on a response from the handler. - + ```typescript restate_service.ts CODE_LOAD::ts/src/concepts/invocations/rpc.ts#rpc_call ``` + --- + ```typescript plain_node_app.ts CODE_LOAD::ts/src/concepts/invocations/ingress/rpc.ts#rpc_call_node ``` @@ -79,15 +78,16 @@ Invocations get a unique identifier. This identifier is used to track the progre --- - **One-way invocations** allow you to trigger an asynchronous action. - This returns an invocation ID with which you can retrieve the result of the invocation later, if desired. + **One-way invocations** allow you to trigger an asynchronous action. - + ```typescript restate_service.ts CODE_LOAD::ts/src/concepts/invocations/one_way.ts#one_way_call ``` + --- + ```typescript plain_node_app.ts CODE_LOAD::ts/src/concepts/invocations/ingress/one_way.ts#one_way_call_node ``` @@ -96,14 +96,16 @@ Invocations get a unique identifier. This identifier is used to track the progre --- - **Delayed invocations** allow you to schedule an invocation for a later point in time. + **Delayed invocations** allow you to schedule an invocation for a later point in time. - + ```typescript restate_service.ts CODE_LOAD::ts/src/concepts/invocations/delayed.ts#delayed_call ``` + --- + ```typescript plain_node_app.ts CODE_LOAD::ts/src/concepts/invocations/ingress/delayed.ts#delayed_call_node ``` @@ -111,19 +113,23 @@ Invocations get a unique identifier. This identifier is used to track the progre + + Learn more about [service communication](/develop/ts/service-communication) and the [SDK clients](/develop/ts/clients) in the TypeScript SDK. - + - **Request-response invocations** allow you to wait on a response from the handler. + **Request-response invocations** allow you to wait on a response from the handler. - + ```java RestateService.java CODE_LOAD::java/src/main/java/concepts/invocations/RpcCalls.java#rpc ``` + --- + ```java PlainJavaService.java CODE_LOAD::java/src/main/java/concepts/invocations/RpcCalls.java#rpc_java ``` @@ -132,15 +138,17 @@ Invocations get a unique identifier. This identifier is used to track the progre --- - **One-way invocations** allow you to trigger an asynchronous action. + **One-way invocations** allow you to trigger an asynchronous action. This returns an invocation ID with which you can retrieve the result of the invocation later, if desired. - + ```java RestateService.java CODE_LOAD::java/src/main/java/concepts/invocations/OneWayCalls.java#one_way_call ``` + --- + ```java PlainJavaService.java CODE_LOAD::java/src/main/java/concepts/invocations/OneWayCalls.java#one_way_call_java ``` @@ -150,13 +158,14 @@ Invocations get a unique identifier. This identifier is used to track the progre --- - **Delayed invocations** allow you to schedule an invocation for a later point in time. + **Delayed invocations** allow you to schedule an invocation for a later point in time. - + ```java RestateService.java CODE_LOAD::java/src/main/java/concepts/invocations/DelayedCalls.java#delayed_call ``` + --- ```java PlainJavaService.java CODE_LOAD::java/src/main/java/concepts/invocations/DelayedCalls.java#delayed_call_java @@ -166,62 +175,45 @@ Invocations get a unique identifier. This identifier is used to track the progre + Learn more about [service communication](/develop/java/service-communication) and the [SDK clients](/develop/java/clients) in the TypeScript SDK. - + - **Request-response invocations** allow you to wait on a response from the handler. + **Request-response invocations** allow you to wait on a response from the handler. ```bash curl localhost:8080/GreeterService/greet \ -H 'content-type: application/json' \ -d '"Hi"' - - curl localhost:8080/GreetCounter/Mary/greet \ - -H 'content-type: application/json' \ - -d '"Hi"' - - curl localhost:8080/MyWorkflow/wf-id-1/run \ - -H 'content-type: application/json' \ - -d '"Hi"' ``` --- - **One-way invocations** allow you to trigger an asynchronous action. + **One-way invocations** allow you to trigger an asynchronous action. This returns an invocation ID with which you can retrieve the result of the invocation later, if desired. ```bash curl localhost:8080/GreeterService/greet/send \ -H 'content-type: application/json' \ -d '"Hi"' - - curl localhost:8080/GreetCounter/Mary/greet/send \ - -H 'content-type: application/json' \ - -d '"Hi"' - - curl localhost:8080/MyWorkflow/wf-id-1/run/send \ - -H 'content-type: application/json' \ - -d '"Hi"' ``` --- - **Delayed invocations** allow you to schedule an invocation for a later point in time. + **Delayed invocations** allow you to schedule an invocation for a later point in time. ```bash curl localhost:8080/GreeterService/greet/send?delay=10s \ -H 'content-type: application/json' \ -d '"Hi"' - - curl localhost:8080/GreetCounter/Mary/greet/send?delay=10s \ - -H 'content-type: application/json' \ - -d '"Hi"' ``` + + Learn more about [invoking services over HTTP](/invoke/http). diff --git a/docs/develop/ts/journaling-results.mdx b/docs/develop/ts/journaling-results.mdx index 530124ce..a0a19ab5 100644 --- a/docs/develop/ts/journaling-results.mdx +++ b/docs/develop/ts/journaling-results.mdx @@ -41,52 +41,15 @@ Operations such as calls, awakeables, and sleep return a `CombineablePromise`. The SDK provides combinators for working with `CombineablePromise`. Restate then logs the order in which they are resolved or rejected, to make them deterministic on replay. +```ts +CODE_LOAD::ts/src/develop/journaling_results.ts#all +``` - - - **Await all** creates a promise that is similar to [`Promise.all()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all), but the outcome is stored in the Restate journal to be deterministically replayable: - - Resolves with an array of results, once all input promises are resolved. - - Rejects when any input promise is rejected. - - ```ts - CODE_LOAD::ts/src/develop/journaling_results.ts#promises?1 - ``` - - --- - - **Await any** creates a promise that is similar to [`Promise.any()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any), - but the outcome is stored in the Restate journal to be deterministically replayable: - - Resolves with the result of the first successfully resolved input promise. - - Rejects when all the input promises are rejected (including when an empty iterable is passed). - This results in an `AggregateError` containing an array of the reasons for rejection. - - ```ts - CODE_LOAD::ts/src/develop/journaling_results.ts#promises?2 - ``` - - --- - - **Race** creates a Promise that is similar to [`Promise.race()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race), - but the outcome is stored in the Restate journal to be deterministically replayable.: - - Resolves when any of the input promises are resolved. - - Rejects when any of the input promises are rejected. - - ```ts - CODE_LOAD::ts/src/develop/journaling_results.ts#promises?3 - ``` - - --- - - **Await all settled** creates a promise that resolves once all the input promises have settled (including when an empty iterable is passed). - It returns an array of objects describing the outcome of each promise, whether resolved or rejected. - Similar to [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled), - but the outcome is stored in the Restate journal to be deterministically replayable. - - ```ts - CODE_LOAD::ts/src/develop/journaling_results.ts#promises?4 - ``` - - +Restate provides the following deterministic combinators: +- `CombineablePromise.all`: similar to [`Promise.all()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all). +- `CombineablePromise.any`: similar to [`Promise.any()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any). +- `CombineablePromise.race`: similar to [`Promise.race()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race). +- `CombineablePromise.allSettled`: similar to [`Promise.allSettled()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled). ## Generating randoms The SDK provides helper functions for the deterministic generation of UUIDs and random numbers. Restate seeds the random number generator with the invocation ID, so it always returns the same value on retries.