four-stroke 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/REVIEW.md ADDED
@@ -0,0 +1,8 @@
1
+ [//]: # Autogenerated by https://github.com/change-engine/ecu/github
2
+
3
+ # Review instructions
4
+
5
+ ## Do not report
6
+
7
+ - PRs opened by dependabot[bot]
8
+ - Any branch matching `dependabot/**`
package/oxfmt.config.ts CHANGED
@@ -1,15 +1 @@
1
- import { defineConfig } from "oxfmt";
2
-
3
- export default defineConfig({
4
- sortImports: {
5
- newlinesBetween: false,
6
- groups: [
7
- ["value-builtin", "value-external"],
8
- ["value-internal", "value-parent", "value-sibling", "value-index"],
9
- { newlinesBetween: true },
10
- "type-import",
11
- "unknown",
12
- ],
13
- },
14
- ignorePatterns: ["worker-configuration.d.ts", "wrangler.jsonc"],
15
- });
1
+ export { default } from "./oxfmt.config.mjs";
package/oxlint.config.mjs CHANGED
@@ -53,13 +53,17 @@ export default defineConfig({
53
53
  "no-anonymous-default-export": "off",
54
54
  "no-continue": "off",
55
55
  "init-declarations": "off",
56
- "prefer-to-be-truthy": "off",
56
+ "vitest/prefer-to-be-truthy": "off",
57
+ "vitest/prefer-to-be-falsy": "off",
57
58
  "vitest/prefer-expect-assertions": "off",
58
59
  "vitest/prefer-importing-vitest-globals": "off",
59
60
  "vitest/no-importing-vitest-globals": "error",
60
61
  "vitest/require-top-level-describe": "off",
61
62
  "vitest/max-expects": "off",
62
63
  "vitest/no-hooks": "off",
64
+ "unicorn/number-literal-case": "off",
65
+ "eslint/one-var": "off",
66
+ "vitest/prefer-called-once": "off",
63
67
  },
64
68
  overrides: [
65
69
  {
package/oxlint.config.ts CHANGED
@@ -1,90 +1 @@
1
- import { defineConfig } from "oxlint";
2
-
3
- export default defineConfig({
4
- plugins: ["eslint", "typescript", "unicorn", "oxc", "import", "promise", "vitest"],
5
- options: {
6
- typeAware: true,
7
- },
8
- categories: {
9
- correctness: "error",
10
- suspicious: "warn",
11
- perf: "error",
12
- style: "warn",
13
- },
14
- rules: {
15
- "no-map-spread": "off",
16
- "no-named-export": "off",
17
- "no-magic-numbers": "off",
18
- "consistent-indexed-object-style": "off",
19
- "id-length": "off",
20
- "no-await-expression-member": "off",
21
- "max-nested-calls": "off",
22
- "sort-keys": "off",
23
- curly: "off",
24
- "switch-case-braces": "off",
25
- "vitest/require-hook": "off",
26
- "no-ternary": "off",
27
- "group-exports": "off",
28
- "exports-last": "off",
29
- "prefer-default-export": "off",
30
- "no-null": "off",
31
- "consistent-type-specifier-style": "off",
32
- "max-statements": "off",
33
- "consistent-type-imports": "error",
34
- "relative-url-style": ["error", "always"],
35
- "no-namespace": "off",
36
- "no-duplicate-imports": ["error", { allowSeparateTypeImports: true }],
37
- "func-style": "off",
38
- "sort-imports": [
39
- "error",
40
- {
41
- ignoreDeclarationSort: true,
42
- ignoreMemberSort: false,
43
- },
44
- ],
45
- "new-cap": "off",
46
- "promise/prefer-await-to-callbacks": "off",
47
- "promise/avoid-new": "off",
48
- "prefer-await-to-then": "off",
49
- "max-params": "off",
50
- "no-underscore-dangle": "off",
51
- "no-nested-ternary": "off",
52
- "unicorn/no-nested-ternary": "off",
53
- "no-anonymous-default-export": "off",
54
- "no-continue": "off",
55
- "init-declarations": "off",
56
- "prefer-to-be-truthy": "off",
57
- "vitest/prefer-expect-assertions": "off",
58
- "vitest/prefer-importing-vitest-globals": "off",
59
- "vitest/no-importing-vitest-globals": "error",
60
- "vitest/require-top-level-describe": "off",
61
- "vitest/max-expects": "off",
62
- "vitest/no-hooks": "off",
63
- },
64
- overrides: [
65
- {
66
- files: ["*.test.ts", "*.spec.ts"],
67
- rules: {
68
- "@typescript-eslint/no-explicit-any": "off",
69
- },
70
- },
71
- {
72
- files: ["*-definitions.ts"],
73
- rules: {
74
- "no-unused-vars": "off",
75
- "@typescript-eslint/no-redundant-type-constituents": "off",
76
- "@typescript-eslint/no-duplicate-type-constituents": "off",
77
- "group-exports": "off",
78
- "exports-last": "off",
79
- "consistent-indexed-object-style": "off",
80
- },
81
- },
82
- {
83
- files: ["bin/*.mjs", "src/cmd.mjs"],
84
- rules: {
85
- "import/no-nodejs-modules": "off",
86
- "prefer-destructuring": "off",
87
- },
88
- },
89
- ],
90
- });
1
+ export { default } from "./oxlint.config.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-stroke",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Simple Cloudflare Worker SSR SPA framework",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -19,17 +19,17 @@
19
19
  "type": "module",
20
20
  "main": "src/fake.ts",
21
21
  "dependencies": {
22
- "@types/react": "^19.2.17",
22
+ "@types/react": "^19.2.18",
23
23
  "openapi-typescript": "^7.13.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@cloudflare/vitest-pool-workers": "^0.18.4",
27
- "knip": "^6.29.0",
28
- "oxfmt": "^0.60.0",
29
- "oxlint": "^1.75.0",
26
+ "@cloudflare/vitest-pool-workers": "^0.22.0",
27
+ "knip": "^6.32.2",
28
+ "oxfmt": "^0.64.0",
29
+ "oxlint": "^1.79.0",
30
30
  "oxlint-tsgolint": "^7.0.2001",
31
31
  "typescript": "^7.0.2",
32
- "vitest": "^4.1.10"
32
+ "vitest": "^4.1.11"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@sentry/cli": "^3.6.0",
package/tsconfig.json CHANGED
@@ -20,5 +20,5 @@
20
20
  "verbatimModuleSyntax": true,
21
21
  "jsx": "react-jsx"
22
22
  },
23
- "exclude": ["../../dist"]
23
+ "exclude": ["../../dist", "oxfmt.config.ts", "oxlint.config.ts"]
24
24
  }
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable */
2
2
  // Generated by Wrangler by running `wrangler types` (hash: f0ebc0bbc8852abc1241a56510ca0186)
3
- // Runtime types generated with workerd@1.20260625.1 2025-09-15 disable_nodejs_fs_module,nodejs_compat
3
+ // Runtime types generated with workerd@1.20260722.1 2025-09-15 disable_nodejs_fs_module,nodejs_compat
4
4
  interface __BaseEnv_Env {
5
5
  }
6
6
  declare namespace Cloudflare {
@@ -523,7 +523,7 @@ declare abstract class DurableObjectNamespace<T extends Rpc.DurableObjectBranded
523
523
  getByName(name: string, options?: DurableObjectNamespaceGetDurableObjectOptions): DurableObjectStub<T>;
524
524
  jurisdiction(jurisdiction: DurableObjectJurisdiction): DurableObjectNamespace<T>;
525
525
  }
526
- type DurableObjectJurisdiction = "eu" | "fedramp" | "fedramp-high";
526
+ type DurableObjectJurisdiction = "eu" | "fedramp" | "fedramp-high" | "us";
527
527
  interface DurableObjectNamespaceNewUniqueIdOptions {
528
528
  jurisdiction?: DurableObjectJurisdiction;
529
529
  }
@@ -12217,6 +12217,13 @@ interface ForwardableEmailMessage extends EmailMessage {
12217
12217
  * @returns A promise that resolves when the email message is replied.
12218
12218
  */
12219
12219
  reply(message: EmailMessage): Promise<EmailSendResult>;
12220
+ /**
12221
+ * Reply to the sender of this email message with a message built from the given
12222
+ * fields. Threading headers (In-Reply-To/References) are set automatically.
12223
+ * @param builder The reply message contents.
12224
+ * @returns A promise that resolves when the email message is replied.
12225
+ */
12226
+ reply(builder: EmailReplyMessageBuilder): Promise<EmailSendResult>;
12220
12227
  }
12221
12228
  /** A file attachment for an email message */
12222
12229
  type EmailAttachment = {
@@ -12237,23 +12244,46 @@ interface EmailAddress {
12237
12244
  name: string;
12238
12245
  email: string;
12239
12246
  }
12247
+ /**
12248
+ * Recipient fields for `SendEmail.send()`. At least one of `to`, `cc`, or
12249
+ * `bcc` must be provided.
12250
+ */
12251
+ type EmailDestinations = {
12252
+ to?: string | EmailAddress | (string | EmailAddress)[];
12253
+ cc?: string | EmailAddress | (string | EmailAddress)[];
12254
+ bcc?: string | EmailAddress | (string | EmailAddress)[];
12255
+ } & ({
12256
+ to: string | EmailAddress | (string | EmailAddress)[];
12257
+ } | {
12258
+ cc: string | EmailAddress | (string | EmailAddress)[];
12259
+ } | {
12260
+ bcc: string | EmailAddress | (string | EmailAddress)[];
12261
+ });
12262
+ /**
12263
+ * Fields shared by all composed emails (no recipients). Used directly by
12264
+ * `ForwardableEmailMessage.reply()`, which always replies to the original
12265
+ * sender, and extended by `EmailMessageBuilder` for `SendEmail.send()`.
12266
+ */
12267
+ interface EmailReplyMessageBuilder {
12268
+ from: string | EmailAddress;
12269
+ subject: string;
12270
+ replyTo?: string | EmailAddress;
12271
+ headers?: Record<string, string>;
12272
+ text?: string;
12273
+ html?: string;
12274
+ attachments?: EmailAttachment[];
12275
+ }
12276
+ /**
12277
+ * Fields for composing an email without constructing raw MIME, for
12278
+ * `SendEmail.send()`. Requires at least one of `to`, `cc`, or `bcc`.
12279
+ */
12280
+ type EmailMessageBuilder = EmailReplyMessageBuilder & EmailDestinations;
12240
12281
  /**
12241
12282
  * A binding that allows a Worker to send email messages.
12242
12283
  */
12243
12284
  interface SendEmail {
12244
12285
  send(message: EmailMessage): Promise<EmailSendResult>;
12245
- send(builder: {
12246
- from: string | EmailAddress;
12247
- to: string | EmailAddress | (string | EmailAddress)[];
12248
- subject: string;
12249
- replyTo?: string | EmailAddress;
12250
- cc?: string | EmailAddress | (string | EmailAddress)[];
12251
- bcc?: string | EmailAddress | (string | EmailAddress)[];
12252
- headers?: Record<string, string>;
12253
- text?: string;
12254
- html?: string;
12255
- attachments?: EmailAttachment[];
12256
- }): Promise<EmailSendResult>;
12286
+ send(builder: EmailMessageBuilder): Promise<EmailSendResult>;
12257
12287
  }
12258
12288
  declare abstract class EmailEvent extends ExtendableEvent {
12259
12289
  readonly message: ForwardableEmailMessage;
@@ -13075,6 +13105,11 @@ declare namespace CloudflareWorkersModule {
13075
13105
  export type WorkflowDurationLabel = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year';
13076
13106
  export type WorkflowSleepDuration = `${number} ${WorkflowDurationLabel}${'s' | ''}` | number;
13077
13107
  export type WorkflowDelayDuration = WorkflowSleepDuration;
13108
+ export type WorkflowDynamicDelayContext = {
13109
+ ctx: WorkflowStepContext<WorkflowDelayFunction>;
13110
+ error: Error;
13111
+ };
13112
+ export type WorkflowDelayFunction = (input: WorkflowDynamicDelayContext) => WorkflowDelayDuration | Promise<WorkflowDelayDuration>;
13078
13113
  export type WorkflowTimeoutDuration = WorkflowSleepDuration;
13079
13114
  export type WorkflowRetentionDuration = WorkflowSleepDuration;
13080
13115
  export type WorkflowBackoff = 'constant' | 'linear' | 'exponential';
@@ -13082,7 +13117,7 @@ declare namespace CloudflareWorkersModule {
13082
13117
  export type WorkflowStepConfig = {
13083
13118
  retries?: {
13084
13119
  limit: number;
13085
- delay: WorkflowDelayDuration | number;
13120
+ delay: WorkflowDelayDuration | number | WorkflowDelayFunction;
13086
13121
  backoff?: WorkflowBackoff;
13087
13122
  };
13088
13123
  timeout?: WorkflowTimeoutDuration | number;
@@ -13108,13 +13143,22 @@ declare namespace CloudflareWorkersModule {
13108
13143
  type: string;
13109
13144
  sensitive?: WorkflowStepSensitivity;
13110
13145
  };
13111
- export type WorkflowStepContext = {
13146
+ export type WorkflowStepContext<Delay = WorkflowDelayDuration | number> = {
13112
13147
  step: {
13113
13148
  name: string;
13114
13149
  count: number;
13115
13150
  };
13116
13151
  attempt: number;
13117
- config: WorkflowStepConfig;
13152
+ config: {
13153
+ retries?: {
13154
+ limit: number;
13155
+ backoff?: WorkflowBackoff;
13156
+ } & (Delay extends WorkflowDelayFunction ? {} : {
13157
+ delay: WorkflowDelayDuration | number;
13158
+ });
13159
+ timeout?: WorkflowTimeoutDuration | number;
13160
+ sensitive?: WorkflowStepSensitivity;
13161
+ };
13118
13162
  };
13119
13163
  export type WorkflowRollbackContext<T = unknown> = {
13120
13164
  ctx: WorkflowStepContext;
@@ -13130,7 +13174,9 @@ declare namespace CloudflareWorkersModule {
13130
13174
  };
13131
13175
  export abstract class WorkflowStep {
13132
13176
  do<T extends Rpc.Serializable<T>>(name: string, callback: (ctx: WorkflowStepContext) => Promise<T>, rollbackOptions?: WorkflowStepRollbackOptions<T>): Promise<T>;
13133
- do<T extends Rpc.Serializable<T>>(name: string, config: WorkflowStepConfig, callback: (ctx: WorkflowStepContext) => Promise<T>, rollbackOptions?: WorkflowStepRollbackOptions<T>): Promise<T>;
13177
+ do<T extends Rpc.Serializable<T>, const C extends WorkflowStepConfig>(name: string, config: C, callback: (ctx: WorkflowStepContext<C['retries'] extends {
13178
+ delay: infer D;
13179
+ } ? D : WorkflowDelayDuration | number>) => Promise<T>, rollbackOptions?: WorkflowStepRollbackOptions<T>): Promise<T>;
13134
13180
  sleep: (name: string, duration: WorkflowSleepDuration) => Promise<void>;
13135
13181
  sleepUntil: (name: string, timestamp: Date | number) => Promise<void>;
13136
13182
  waitForEvent<T extends Rpc.Serializable<T>>(name: string, options: {
@@ -14040,6 +14086,7 @@ declare namespace TailStream {
14040
14086
  readonly dispatchNamespace?: string;
14041
14087
  readonly entrypoint?: string;
14042
14088
  readonly executionModel: string;
14089
+ readonly durableObjectId?: string;
14043
14090
  readonly scriptName?: string;
14044
14091
  readonly scriptTags?: string[];
14045
14092
  readonly scriptVersion?: ScriptVersion;
@@ -14594,6 +14641,13 @@ interface WorkflowError {
14594
14641
  code?: number;
14595
14642
  message: string;
14596
14643
  }
14644
+ interface WorkflowInstanceTerminateOptions {
14645
+ /**
14646
+ * If true, run registered rollback handlers before terminating the instance.
14647
+ * Only steps that registered rollback handlers are rolled back.
14648
+ */
14649
+ rollback?: boolean;
14650
+ }
14597
14651
  interface WorkflowInstanceRestartOptions {
14598
14652
  /**
14599
14653
  * Restart from a specific step. If omitted, the instance restarts from the beginning.
@@ -14627,8 +14681,9 @@ declare abstract class WorkflowInstance {
14627
14681
  public resume(): Promise<void>;
14628
14682
  /**
14629
14683
  * Terminate the instance. If it is errored, terminated or complete, an error will be thrown.
14684
+ * @param options Options for termination, including whether registered rollback handlers should run.
14630
14685
  */
14631
- public terminate(): Promise<void>;
14686
+ public terminate(options?: WorkflowInstanceTerminateOptions): Promise<void>;
14632
14687
  /**
14633
14688
  * Restart the instance. Optionally restart from a specific step, preserving
14634
14689
  * cached results for all steps before it.