Compare commits

...

14 Commits

Author SHA1 Message Date
188f8057bf 2.0.15 2023-10-03 19:19:54 +02:00
99cb86258e fix(core): update 2023-10-03 19:19:54 +02:00
83976fa3f4 2.0.14 2023-10-03 16:20:35 +02:00
fe81307ca6 fix(core): update 2023-10-03 16:20:34 +02:00
3a119b50a2 2.0.13 2023-10-03 13:19:39 +02:00
d3332ccb3f fix(core): update 2023-10-03 13:19:38 +02:00
776eba09e9 2.0.12 2023-10-03 12:47:38 +02:00
b41ff5d495 fix(core): update 2023-10-03 12:47:38 +02:00
5f5f9db884 2.0.11 2023-10-03 12:47:13 +02:00
876042b446 fix(core): update 2023-10-03 12:47:12 +02:00
df2924577b 2.0.10 2023-10-03 07:53:29 +02:00
4abaea84f8 fix(core): update 2023-10-03 07:53:28 +02:00
de454b4c8d 2.0.9 2023-09-11 18:39:53 +02:00
961685b5bd fix(core): update 2023-09-11 18:39:52 +02:00
9 changed files with 1598 additions and 870 deletions

View File

@ -119,6 +119,6 @@ jobs:
run: | run: |
npmci node install stable npmci node install stable
npmci npm install npmci npm install
pnpm install -g @gitzone/tsdoc pnpm install -g @git.zone/tsdoc
npmci command tsdoc npmci command tsdoc
continue-on-error: true continue-on-error: true

View File

@ -1,6 +1,6 @@
{ {
"name": "@push.rocks/smartstate", "name": "@push.rocks/smartstate",
"version": "2.0.8", "version": "2.0.15",
"private": false, "private": false,
"description": "a package that handles state in a good way", "description": "a package that handles state in a good way",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@ -14,19 +14,20 @@
"buildDocs": "tsdoc" "buildDocs": "tsdoc"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.66", "@git.zone/tsbuild": "^2.1.70",
"@gitzone/tsbundle": "^2.0.8", "@git.zone/tsbundle": "^2.0.8",
"@gitzone/tsrun": "^1.2.44", "@git.zone/tsrun": "^1.2.46",
"@gitzone/tstest": "^1.0.77", "@git.zone/tstest": "^1.0.81",
"@push.rocks/tapbundle": "^5.0.12", "@push.rocks/tapbundle": "^5.0.15",
"@types/node": "^20.4.5" "@types/node": "^20.8.0"
}, },
"dependencies": { "dependencies": {
"@push.rocks/isohash": "^2.0.1", "@push.rocks/isohash": "^2.0.1",
"@push.rocks/lik": "^6.0.3", "@push.rocks/lik": "^6.0.5",
"@push.rocks/smartjson": "^5.0.6", "@push.rocks/smartjson": "^5.0.10",
"@push.rocks/smartpromise": "^4.0.3", "@push.rocks/smartpromise": "^4.0.3",
"@push.rocks/smartrx": "^3.0.6" "@push.rocks/smartrx": "^3.0.6",
"@push.rocks/webstore": "^2.0.13"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

2358
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ tap.test('should create a new SmartState', async () => {
}); });
tap.test('should create a new StatePart', async () => { tap.test('should create a new StatePart', async () => {
testStatePart = testState.getStatePart<TStatePartPayload>('testStatePart', { testStatePart = await testState.getStatePart<TStatePartPayload>('testStatePart', {
currentFavorites: [], currentFavorites: [],
deep: { deep: {
hi: 2, hi: 2,

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartstate', name: '@push.rocks/smartstate',
version: '2.0.8', version: '2.0.15',
description: 'a package that handles state in a good way' description: 'a package that handles state in a good way'
} }

View File

@ -1,6 +1,8 @@
import * as plugins from './smartstate.plugins.js'; import * as plugins from './smartstate.plugins.js';
import { StatePart } from './smartstate.classes.statepart.js'; import { StatePart } from './smartstate.classes.statepart.js';
export type TInitMode = 'soft' | 'mandatory' | 'force' | 'persistent';
/** /**
* Smartstate takes care of providing state * Smartstate takes care of providing state
*/ */
@ -18,11 +20,11 @@ export class Smartstate<StatePartNameType> {
* @param initialArg * @param initialArg
* @param initMode * @param initMode
*/ */
public getStatePart<PayloadType>( public async getStatePart<PayloadType>(
statePartNameArg: string & StatePartNameType, statePartNameArg: string & StatePartNameType,
initialArg?: PayloadType, initialArg?: PayloadType,
initMode?: 'soft' | 'mandatory' | 'force' initMode?: TInitMode
): StatePart<StatePartNameType, PayloadType> { ): Promise<StatePart<StatePartNameType, PayloadType>> {
if (this.statePartMap[statePartNameArg as any]) { if (this.statePartMap[statePartNameArg as any]) {
if (initialArg && (!initMode || initMode !== 'soft')) { if (initialArg && (!initMode || initMode !== 'soft')) {
throw new Error( throw new Error(
@ -36,7 +38,7 @@ export class Smartstate<StatePartNameType> {
`${statePartNameArg} does not yet exist, yet you don't provide an initial state` `${statePartNameArg} does not yet exist, yet you don't provide an initial state`
); );
} }
return this.createStatePart<PayloadType>(statePartNameArg, initialArg); return this.createStatePart<PayloadType>(statePartNameArg, initialArg, initMode);
} }
} }
@ -45,12 +47,24 @@ export class Smartstate<StatePartNameType> {
* @param statePartName * @param statePartName
* @param initialPayloadArg * @param initialPayloadArg
*/ */
private createStatePart<PayloadType>( private async createStatePart<PayloadType>(
statePartName: StatePartNameType, statePartName: StatePartNameType,
initialPayloadArg: PayloadType initialPayloadArg: PayloadType,
): StatePart<StatePartNameType, PayloadType> { initMode?: TInitMode
const newState = new StatePart<StatePartNameType, PayloadType>(statePartName); ): Promise<StatePart<StatePartNameType, PayloadType>> {
newState.setState(initialPayloadArg); const newState = new StatePart<StatePartNameType, PayloadType>(
statePartName,
initMode === 'persistent' ? {
dbName: 'smartstate',
storeName: statePartName as any,
} : null
);
await newState.init();
const currentState = newState.getState();
await newState.setState({
...initialPayloadArg,
...currentState,
});
this.statePartMap[statePartName as any] = newState; this.statePartMap[statePartName as any] = newState;
return newState; return newState;
} }

View File

@ -7,8 +7,31 @@ export class StatePart<TStatePartName, TStatePayload> {
public stateStore: TStatePayload; public stateStore: TStatePayload;
private cumulativeDeferred = plugins.smartpromise.cumulativeDefer(); private cumulativeDeferred = plugins.smartpromise.cumulativeDefer();
constructor(nameArg: TStatePartName) { private webStoreOptions: plugins.webstore.IWebStoreOptions;
private webStore: plugins.webstore.WebStore<TStatePayload> | null = null; // Add WebStore instance
constructor(nameArg: TStatePartName, webStoreOptionsArg?: plugins.webstore.IWebStoreOptions) {
this.name = nameArg; this.name = nameArg;
// Initialize WebStore if webStoreOptions are provided
if (webStoreOptionsArg) {
this.webStoreOptions = webStoreOptionsArg;
}
}
/**
* initializes the webstore
*/
public async init() {
if (this.webStoreOptions) {
this.webStore = new plugins.webstore.WebStore<TStatePayload>(this.webStoreOptions);
await this.webStore.init();
const storedState = await this.webStore.get(String(this.name));
if (storedState) {
this.stateStore = storedState;
this.notifyChange();
}
}
} }
/** /**
@ -22,9 +45,14 @@ export class StatePart<TStatePartName, TStatePayload> {
* sets the stateStore to the new state * sets the stateStore to the new state
* @param newStateArg * @param newStateArg
*/ */
public setState(newStateArg: TStatePayload) { public async setState(newStateArg: TStatePayload) {
this.stateStore = newStateArg; this.stateStore = newStateArg;
this.notifyChange(); this.notifyChange();
// Save state to WebStore if initialized
if (this.webStore) {
await this.webStore.set(String(this.name), newStateArg);
}
} }
/** /**
@ -89,10 +117,11 @@ export class StatePart<TStatePartName, TStatePayload> {
/** /**
* dispatches an action on the statepart level * dispatches an action on the statepart level
*/ */
public async dispatchAction<T>(stateAction: StateAction<TStatePayload, T>, actionPayload: T) { public async dispatchAction<T>(stateAction: StateAction<TStatePayload, T>, actionPayload: T): Promise<TStatePayload> {
await this.cumulativeDeferred.promise; await this.cumulativeDeferred.promise;
const newState = await stateAction.actionDef(this, actionPayload); const newState = await stateAction.actionDef(this, actionPayload);
this.setState(newState); await this.setState(newState);
return this.getState();
} }
/** /**

View File

@ -2,5 +2,6 @@ import * as isohash from '@push.rocks/isohash';
import * as smartjson from '@push.rocks/smartjson'; import * as smartjson from '@push.rocks/smartjson';
import * as smartpromise from '@push.rocks/smartpromise'; import * as smartpromise from '@push.rocks/smartpromise';
import * as smartrx from '@push.rocks/smartrx'; import * as smartrx from '@push.rocks/smartrx';
import * as webstore from '@push.rocks/webstore';
export { isohash, smartjson, smartpromise, smartrx }; export { isohash, smartjson, smartpromise, smartrx, webstore };

View File

@ -3,9 +3,12 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"useDefineForClassFields": false, "useDefineForClassFields": false,
"target": "ES2022", "target": "ES2022",
"module": "ES2022", "module": "NodeNext",
"moduleResolution": "nodenext", "moduleResolution": "NodeNext",
"esModuleInterop": true, "esModuleInterop": true,
"verbatimModuleSyntax": true, "verbatimModuleSyntax": true
} },
"exclude": [
"dist_*/**/*.d.ts"
]
} }