Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/angular-vite-pwa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"dependencies": {
"@angular/core": "^21.1.0",
"@angular/platform-browser": "^21.1.0",
"@evolu/common": "latest",
"@evolu/web": "latest"
"@evolu/common": "workspace:*",
"@evolu/web": "workspace:*"
},
"devDependencies": {
"@analogjs/vite-plugin-angular": "^2.2.2",
Expand Down
6 changes: 3 additions & 3 deletions examples/react-electron/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
"preview": "vite preview"
},
"dependencies": {
"@evolu/common": "latest",
"@evolu/react": "latest",
"@evolu/react-web": "latest",
"@evolu/common": "workspace:*",
"@evolu/react": "workspace:*",
"@evolu/react-web": "workspace:*",
"react": "19.2.4",
"react-dom": "19.2.4"
},
Expand Down
6 changes: 3 additions & 3 deletions examples/react-expo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
},
"dependencies": {
"@blazejkustra/react-native-alert": "^1.0.0",
"@evolu/common": "latest",
"@evolu/react": "latest",
"@evolu/react-native": "latest",
"@evolu/common": "workspace:*",
"@evolu/react": "workspace:*",
"@evolu/react-native": "workspace:*",
"@expo/metro-runtime": "^6.1.2",
"@expo/vector-icons": "^15.0.3",
"abort-signal-polyfill": "^1.0.0",
Expand Down
6 changes: 3 additions & 3 deletions examples/react-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
"dev": "next dev --webpack"
},
"dependencies": {
"@evolu/common": "latest",
"@evolu/react": "latest",
"@evolu/react-web": "latest",
"@evolu/common": "workspace:*",
"@evolu/react": "workspace:*",
"@evolu/react-web": "workspace:*",
"@tabler/icons-react": "^3.36.1",
"clsx": "^2.1.1",
"next": "^16.1.3",
Expand Down
6 changes: 3 additions & 3 deletions examples/react-vite-pwa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"preview": "vite preview"
},
"dependencies": {
"@evolu/common": "latest",
"@evolu/react": "latest",
"@evolu/react-web": "latest",
"@evolu/common": "workspace:*",
"@evolu/react": "workspace:*",
"@evolu/react-web": "workspace:*",
"@tabler/icons-react": "^3.36.1",
"clsx": "^2.1.1",
"react": "19.2.4",
Expand Down
6 changes: 3 additions & 3 deletions examples/vue-vite-pwa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"preview": "vite preview"
},
"dependencies": {
"@evolu/common": "latest",
"@evolu/vue": "latest",
"@evolu/web": "latest",
"@evolu/common": "workspace:*",
"@evolu/vue": "workspace:*",
"@evolu/web": "workspace:*",
"vue": "^3.5.26",
"workbox-window": "^7.4.0"
},
Expand Down
16 changes: 8 additions & 8 deletions packages/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"default": "./dist/src/index.js",
"react-native": "./dist/src/index.js"
"react-native": "./dist/src/index.js",
"default": "./dist/src/index.js"
},
"./expo-sqlite": {
"types": "./dist/src/exports/expo-sqlite.d.ts",
"default": "./dist/src/exports/expo-sqlite.js",
"react-native": "./dist/src/exports/expo-sqlite.js",
"browser": "./dist/src/web.js"
"browser": "./dist/src/web.js",
"default": "./dist/src/exports/expo-sqlite.js"
},
"./expo-op-sqlite": {
"types": "./dist/src/exports/expo-op-sqlite.d.ts",
"default": "./dist/src/exports/expo-op-sqlite.js",
"react-native": "./dist/src/exports/expo-op-sqlite.js",
"browser": "./dist/src/web.js"
"browser": "./dist/src/web.js",
"default": "./dist/src/exports/expo-op-sqlite.js"
},
"./bare-op-sqlite": {
"types": "./dist/src/exports/bare-op-sqlite.d.ts",
"default": "./dist/src/exports/bare-op-sqlite.js",
"react-native": "./dist/src/exports/bare-op-sqlite.js",
"browser": "./dist/src/web.js"
"browser": "./dist/src/web.js",
"default": "./dist/src/exports/bare-op-sqlite.js"
}
},
"typesVersions": {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-native/test/Task.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ describe("createRunner", () => {
const previousHandler = vi.fn();
mockErrorUtils.getGlobalHandler.mockReturnValue(previousHandler);

await using _run = createRunner();
const console = testCreateConsole();
await using _run = createRunner({ console });

// Get the handler that was registered
const handler = mockErrorUtils.setGlobalHandler.mock.calls[0][0];
Expand Down
47 changes: 7 additions & 40 deletions packages/web/test/Task.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe("createRunner", () => {
expect(run.deps.customValue).toBe(42);
});

describe("listener registration (mocked)", () => {
describe("event listeners", () => {
const originalAddEventListener = globalThis.addEventListener;
const originalRemoveEventListener = globalThis.removeEventListener;

Expand Down Expand Up @@ -57,16 +57,13 @@ describe("createRunner", () => {
addedListeners.get("unhandledrejection"),
);
});
});

describe("error handling (real browser events)", () => {
test("catches and logs ErrorEvent", async () => {
test("error handler logs ErrorEvent", async () => {
const console = testCreateConsole();
await using _run = createRunner({ console });

globalThis.dispatchEvent(
new ErrorEvent("error", { error: new Error("test error") }),
);
const handler = addedListeners.get("error")!;
handler(new ErrorEvent("error", { error: new Error("test error") }));

Comment on lines +61 to 67
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove non‑null assertion on addedListeners.get("error").
Lint flags ! here; use an explicit assertion to narrow the type before calling the handler.

🔧 Suggested fix
-      const handler = addedListeners.get("error")!;
-      handler(new ErrorEvent("error", { error: new Error("test error") }));
+      const handler = addedListeners.get("error");
+      expect(handler).toBeDefined();
+      handler?.(new ErrorEvent("error", { error: new Error("test error") }));
🧰 Tools
🪛 GitHub Actions: CI

[warning] 65-65: lint/style/noNonNullAssertion: Forbidden non-null assertion. Consider avoiding the '!' postfix operator.

🤖 Prompt for AI Agents
In `@packages/web/test/Task.test.ts` around lines 61 - 67, The test currently uses
a non-null assertion on addedListeners.get("error") — replace the `!` with an
explicit runtime/type-narrowing assertion: retrieve the value into `handler`,
assert it is defined (e.g., `if (!handler) throw new Error("error handler not
registered")` or an `expect(handler).toBeDefined()`), then call `handler(new
ErrorEvent(...))`; update references to `addedListeners.get("error")` and the
`handler` variable in the "error handler logs ErrorEvent" test to remove the `!`
and perform the explicit check before invoking.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Podívej se jestli je to validní a případně fixni

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

const entries = console.getEntriesSnapshot();
expect(entries).toHaveLength(1);
Expand All @@ -78,11 +75,12 @@ describe("createRunner", () => {
});
});

test("catches and logs PromiseRejectionEvent", async () => {
test("error handler logs PromiseRejectionEvent", async () => {
const console = testCreateConsole();
await using _run = createRunner({ console });

globalThis.dispatchEvent(
const handler = addedListeners.get("unhandledrejection")!;
handler(
new PromiseRejectionEvent("unhandledrejection", {
promise: Promise.resolve(),
reason: new Error("test rejection"),
Expand All @@ -98,36 +96,5 @@ describe("createRunner", () => {
error: { message: "test rejection" },
});
});

test("stops catching events after dispose", async () => {
const console = testCreateConsole();

// First verify events ARE caught before dispose
{
await using _run = createRunner({ console });
globalThis.dispatchEvent(
new ErrorEvent("error", { error: new Error("before dispose") }),
);
}
expect(console.getEntriesSnapshot()).toHaveLength(1);

// Verify events are NOT caught after dispose
// Prevent vitest from treating dispatched error as unhandled
const suppress = (e: Event) => e.preventDefault();
globalThis.addEventListener("error", suppress);

const beforeCount = console.getEntriesSnapshot().length;

globalThis.dispatchEvent(
new ErrorEvent("error", {
error: new Error("after dispose"),
cancelable: true,
}),
);

globalThis.removeEventListener("error", suppress);

expect(console.getEntriesSnapshot()).toHaveLength(beforeCount);
});
});
});