Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
caf17b3
Fix deep cloning for complex objects (Dayjs, Moment, etc.)
DanWahlin Feb 6, 2026
7c1e56c
Modernize dev dependencies
DanWahlin Feb 6, 2026
898a56f
Switch build and test tooling to Vite + Vitest
DanWahlin Feb 6, 2026
02604bc
Code quality fixes (non-breaking)
DanWahlin Feb 6, 2026
5b272c1
Fix Vite build target for backward compat with Angular 15 webpack
DanWahlin Feb 6, 2026
11a4049
Modernize observable-store-extensions to Vite + TS 5.9
DanWahlin Feb 6, 2026
53579c2
v3.0.0 — Breaking changes
DanWahlin Feb 6, 2026
3c54079
Upgrade React, Vue, and JS samples to latest versions
DanWahlin Feb 6, 2026
d282510
Upgrade Angular samples to Angular 21
DanWahlin Feb 6, 2026
cdd259b
Update year
DanWahlin Feb 6, 2026
af8aec6
Re-enable Redux DevTools extension in angular-store sample
DanWahlin Feb 6, 2026
d3dcd64
Use file: references for local modules (v3 not yet published to npm)
DanWahlin Feb 6, 2026
3e2ef01
Add root build script for local dev setup (modules must be built befo…
DanWahlin Feb 6, 2026
7a37154
Pin TypeScript to 5.8.x to match API Extractor (removes build warning)
DanWahlin Feb 6, 2026
d020fd1
Add zone.js + provideZoneChangeDetection to all Angular samples (fixe…
DanWahlin Feb 6, 2026
9ca27a4
Align Angular samples with Angular 21 scaffold conventions
DanWahlin Feb 6, 2026
d7f2c3a
Add comprehensive test coverage: 103 tests (was 62)
DanWahlin Feb 6, 2026
22709b5
Add npm test script to root package.json
DanWahlin Feb 6, 2026
5c63bee
Pre-publish prep: CHANGELOG.md, README cleanup, CI update
DanWahlin Feb 6, 2026
1476836
Add compatibility table to README (Angular 17+, v2.x for older)
DanWahlin Feb 6, 2026
291001a
Clean up README for v3
DanWahlin Feb 6, 2026
f751913
Simplify compatibility section
DanWahlin Feb 6, 2026
d6280ac
Pin Angular 14-16 compat to v2.2.15 (last 2.x release)
DanWahlin Feb 6, 2026
f487c4c
Fix API docs accuracy and typos
DanWahlin Feb 6, 2026
2e78427
Add Vue.js and JavaScript sections to README
DanWahlin Feb 6, 2026
51754a3
Remove vue-store sample (empty scaffold, never used Observable Store)
DanWahlin Feb 6, 2026
6bcd8a6
Improve CI: cache both lockfiles, validate samples, add npm publish o…
DanWahlin Feb 6, 2026
e45d476
refactor: code quality improvements across Observable-Store codebase
DanWahlin Feb 6, 2026
eba9628
CI: trigger publish on 'release:' commit message instead of tags
DanWahlin Feb 6, 2026
577eeba
CI: add manual workflow dispatch with dry-run publish option
DanWahlin Feb 6, 2026
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
133 changes: 91 additions & 42 deletions .github/workflows/nodejs-build-validation.yml
Original file line number Diff line number Diff line change
@@ -1,59 +1,108 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Build
name: Build & Test

on:
push:
branches: [ "main" ]
branches: [main]
pull_request:
branches: [ "main" ]

jobs:
build-observable-store:
branches: [main]
workflow_dispatch:
inputs:
publish:
description: 'Run publish step (dry-run by default)'
type: boolean
default: true
dry_run:
description: 'Dry run (no actual publish)'
type: boolean
default: true

jobs:
build-and-test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./modules/observable-store/

strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
node-version: [18.x, 20.x, 22.x]

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: ./modules/observable-store/package-lock.json
- run: npm ci
- run: npm run build --if-present
- run: npm test

build-observable-store-extensions:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: |
modules/observable-store/package-lock.json
modules/observable-store-extensions/package-lock.json

- name: Build modules
run: npm run build

- name: Run tests
run: npm test

build-samples:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./modules/observable-store-extensions/
needs: build-and-test

strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v4

- name: Use Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 22.x
cache: npm
cache-dependency-path: |
modules/observable-store/package-lock.json
modules/observable-store-extensions/package-lock.json

- name: Build modules
run: npm run build

- name: Build Angular Store sample
working-directory: samples/angular-store
run: npm install && npm run build

- name: Build React Store sample
working-directory: samples/react-store
run: npm install && npm run build

- name: Build JavaScript demo
working-directory: samples/javascript-demo
run: npm install && npm run build

publish:
if: |
(github.event_name == 'push' && github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'release:')) ||
(github.event_name == 'workflow_dispatch' && inputs.publish)
needs: [build-and-test, build-samples]
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: ./modules/observable-store-extensions/package-lock.json
- run: npm ci
- run: npm run build --if-present
- uses: actions/checkout@v4

- name: Use Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 22.x
registry-url: https://registry.npmjs.org

- name: Build modules
run: npm run build

- name: Publish observable-store
working-directory: modules/observable-store
run: npm publish --provenance --access public ${{ (github.event_name == 'workflow_dispatch' && inputs.dry_run) && '--dry-run' || '' }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Publish observable-store-extensions
working-directory: modules/observable-store-extensions
run: npm publish --provenance --access public ${{ (github.event_name == 'workflow_dispatch' && inputs.dry_run) && '--dry-run' || '' }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# compiled output
modules/**/dist
samples/**/dist
tmp
out-tsc
.angular
Expand Down
70 changes: 70 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Changelog

## 3.0.0 — February 2026

### Breaking Changes

- **Removed `includeStateChangesOnSubscribe` setting.** This was deprecated in v2.1.0. Use `stateWithPropertyChanges` or `globalStateWithPropertyChanges` instead.
- **ES2022 build target.** The library now targets ES2022, which means it requires a modern JavaScript runtime. Older bundlers that cannot handle native classes (e.g., Angular 15's webpack) are no longer supported. If you need Angular 15 support, stay on v2.x.
- **Dual ESM + CJS output.** The package now ships both ES module (`observable-store.js`) and CommonJS (`observable-store.cjs`) builds via the `exports` field in `package.json`. Most bundlers will resolve this automatically.

### New Features

- **`destroy()` method.** Call `destroy()` on a service to unregister it from the global store and complete its state dispatchers. This prevents memory leaks when services are created and destroyed dynamically (e.g., in Angular's `ngOnDestroy`).
- **Deep cloning for complex objects.** Objects with custom prototypes (Dayjs, Moment.js, Luxon DateTime, etc.) are now cloned correctly using a 4-strategy cascade: `clone()` → constructor → `Object.create` → reference fallback. Previously, `JSON.parse(JSON.stringify())` would strip prototype methods and corrupt these objects. (Fixes [#314](https://github.com/DanWahlin/Observable-Store/issues/314))
- **Deep Map/Set cloning.** Map and Set values are now individually deep-cloned rather than shallow-copied, preventing mutation leaks across state snapshots.

### Improvements

- **Vite build system.** Replaced `tsc` with [Vite](https://vitejs.dev/) library mode for building both `observable-store` and `observable-store-extensions`.
- **Vitest test framework.** Replaced Jasmine with [Vitest](https://vitest.dev/). 103 tests run in ~50ms.
- **TypeScript 5.8.** Upgraded from TypeScript 4.9.
- **Reduced dev dependencies.** From 8 to 4 (removed jasmine, ts-node, @types/jasmine, @types/node).
- **Code quality.** `hasOwnProperty()` → `Object.hasOwn()`, `var` → `const`, `==` → `===`, removed dead imports, reduced redundant cloning in `setState()`.

### Samples

All sample applications have been upgraded to current framework versions:
- **Angular:** 15 → 21 (standalone components, `@if`/`@for` control flow, `provideZoneChangeDetection`)
- **React:** 16 → 19 (hooks, React Router v7, Vite)
- **Vue:** 2 → 3.5 (Composition API, Vue Router v4, Vite)
- **JavaScript:** webpack → Vite

### Extensions

- `@codewithdan/observable-store-extensions` has been modernized with Vite + TypeScript 5.8 and ships dual ESM/CJS builds matching the core library.

---

## 2.2.15 — November 2022

- New `isStoreInitialized` property. Thanks to [Jason Landbridge](https://github.com/JasonLandbridge).

## 2.2.13 — August 2021

- Added `getStateSliceProperty()` function. Thanks to [Connor Smith](https://github.com/ConnorSmith-pf).

## 2.2.10 — May 2020

- Fixed internal cloning to respect `deepClone` parameter. Thanks to [Steve-RW](https://github.com/Steve-RW).

## 2.2.9 — May 2020

- Added Map and Set cloning support. Thanks to [Chris Andrade](https://github.com/chrisjandrade).

## 2.2.3 — December 2019

- Added Redux DevTools extension (`@codewithdan/observable-store-extensions`).
- Added `allStoreServices` property and `addExtension()` function.

## 2.1.0 — October 2019

- Added `stateWithPropertyChanges` and `globalStateWithPropertyChanges` observables.
- Deprecated `includeStateChangesOnSubscribe`.

## 2.0.0 — October 2019

- Strongly-typed API.
- RxJS moved to peer dependency.
- Added `globalSettings`.
- Added cloning for state immutability.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Dan Wahlin
Copyright (c) 2026 Dan Wahlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading