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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.5.3] - 2026-03-31

### Fixed

- **Symbol property access on proxied state** — accessing or setting Symbol-keyed properties (e.g. those used internally by Svelte or JavaScript runtimes) on a proxied state object no longer throws or triggers change tracking incorrectly; symbols are now passed through transparently

## [1.5.2] - 2026-03-31

### Fixed
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<link rel="icon" href="favicon.png" />
<title>svstate demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script type="module" crossorigin src="/svstate/assets/index-2ubidnA3.js"></script>
<script type="module" crossorigin src="/svstate/assets/index-CXrV2wig.js"></script>
<link rel="stylesheet" crossorigin href="/svstate/assets/index-Ck8pee3s.css">
</head>

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "svstate",
"version": "1.5.2",
"version": "1.5.3",
"description": "Supercharged $state() for Svelte 5: deep reactive proxy with validation, cross-field rules, computed & side-effects",
"author": "BCsabaEngine",
"license": "ISC",
Expand Down
11 changes: 8 additions & 3 deletions src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const ChangeProxy = <T extends object>(source: T, changed: ProxyChanged<T
const createProxy = (target: object, parentPath: string): object =>
new Proxy(target, {
get(object, property) {
const value = (object as Record<string, unknown>)[property as string];
if (typeof property === 'symbol') return (object as Record<symbol, unknown>)[property];
const value = (object as Record<string, unknown>)[property];
if (isProxiable(value)) {
const pathSegment = Number.isInteger(Number(property)) ? '' : String(property);
const childPath = pathSegment ? (parentPath ? `${parentPath}.${pathSegment}` : pathSegment) : parentPath;
Expand All @@ -30,9 +31,13 @@ export const ChangeProxy = <T extends object>(source: T, changed: ProxyChanged<T
return value;
},
set(object, property, incomingValue) {
const oldValue = (object as Record<string, unknown>)[property as string];
if (typeof property === 'symbol') {
(object as Record<symbol, unknown>)[property] = incomingValue;
return true;
}
const oldValue = (object as Record<string, unknown>)[property];
if (oldValue !== incomingValue) {
(object as Record<string, unknown>)[property as string] = incomingValue;
(object as Record<string, unknown>)[property] = incomingValue;
const pathSegment = Number.isInteger(Number(property)) ? '' : String(property);
const fullPath = pathSegment ? (parentPath ? `${parentPath}.${pathSegment}` : pathSegment) : parentPath;
changed(data as T, fullPath, incomingValue, oldValue);
Expand Down
Loading