Updated documentation
All checks were successful
Build / Build NPM Project (push) Successful in 16s
Build / Tag Version (push) Successful in 3s
Build / Publish (push) Successful in 3s

This commit is contained in:
Zakary Timson 2023-12-27 17:23:17 -05:00
parent 039b393eeb
commit 9757b7aaca
5 changed files with 188 additions and 48 deletions

View File

@ -41,10 +41,6 @@ jobs:
uses: ztimson/actions/cache@develop uses: ztimson/actions/cache@develop
with: with:
pattern: dist pattern: dist
- name: Upload Wiki
uses: ztimson/actions/wiki@develop
tag: tag:
name: Tag Version name: Tag Version
needs: build needs: build

201
README.md
View File

@ -20,8 +20,7 @@
--- ---
<div> <div>
<a href="https://git.zakscode.com/ztimson/persist/wiki" target="_blank">Documentation</a> <a href="https://git.zakscode.com/ztimson/persist/releases" target="_blank">Release Notes</a>
<a href="https://git.zakscode.com/ztimson/persist/releases" target="_blank">Release Notes</a>
<a href="https://git.zakscode.com/ztimson/persist/issues/new?template=.github%2fissue_template%2fbug.md" target="_blank">Report a Bug</a> <a href="https://git.zakscode.com/ztimson/persist/issues/new?template=.github%2fissue_template%2fbug.md" target="_blank">Report a Bug</a>
<a href="https://git.zakscode.com/ztimson/persist/issues/new?template=.github%2fissue_template%2fenhancement.md" target="_blank">Request a Feature</a> <a href="https://git.zakscode.com/ztimson/persist/issues/new?template=.github%2fissue_template%2fenhancement.md" target="_blank">Request a Feature</a>
</div> </div>
@ -32,15 +31,54 @@
## Table of Contents ## Table of Contents
- [Persist](#top) - [Persist](#top)
- [About](#about) - [About](#about)
- [Built With](#built-with) - [Examples](#examples)
- [Built With](#built-with)
- [Setup](#setup) - [Setup](#setup)
- [Production](#production) - [Production](#production)
- [Development](#development) - [Development](#development)
- [Documentation](#documentation)
- [Classes](#classes)
- [Decorators](#decorators)
- [Types](#types)
- [License](#license) - [License](#license)
## About ## About
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Persist is an updated version of [webstorage-decorators](https://git.zakscode.com/ztimson/webstorage-decorators), a library which saves variables to local or session storage.
This library aims to improve upon the original's limitations by using the new [Proxy Objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). Improvements include:
- Supports both objects & decorators
- Proxy object ensures all changes are tracked including impure functions
- [Proto]types and functions can be preserved by passing the `type` option
JavaScript's decorators are currently undergoing changes to the API overseen by [TC39](https://tc39.es) and currently have no support for property decorators. [Experimental decorators](https://www.typescriptlang.org/tsconfig#experimentalDecorators) must be enabled to work properly.
### Examples
Using objects:
```ts
import {Persist} from 'ztimson/persist';
// Proxy Object (Always access/modify using `.value`):
let theme = new Persist<string>('theme', {default: 'os'});
console.log(theme.value) // Output: os
theme.value = 'light'; // Changes will be synced to localStorage['theme'];
```
Using decorators:
```ts
import {persist} from 'ztimson/persist';
// Using decorators
class Theme {
@persist({key: 'theme', default: 'os'}) current!: string;
}
const theme = new Theme();
console.log(theme.current); // Output: light
theme.current = 'dark'; // You can ommit `.value` when using the decorator
```
### Built With ### Built With
[![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white)](https://typescriptlang.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white)](https://typescriptlang.org/)
@ -69,28 +107,8 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
... ...
} }
``` ```
3. Use persist: 3. Import & use, see [examples above](#examples)
```ts
import {Persist} from 'ztimson/persist';
// Proxy Object (Always access/modify using `.value`):
let theme = new Persist<string>('theme', {default: 'os'});
console.log(theme.value) // Output: os
theme.value = 'light'; // Changes will be synced to localStorage['theme'];
```
```ts
import {persist} from 'ztimson/persist';
// Using decorators
class Theme {
@persist({key: 'theme', default: 'os'}) current!: string;
}
const theme = new Theme();
console.log(theme.current); // Output: light
theme.current = 'dark'; // You can ommit `.value` when using the decorator
```
</details> </details>
<details> <details>
@ -110,6 +128,135 @@ theme.current = 'dark'; // You can ommit `.value` when using the decorator
</details> </details>
## Documentation
<details>
<summary>
<h3 id="classes" style="display: inline">
Classes
</h3>
</summary>
Create a proxy object which wraps your data so any changes can be intercepted & synced with storage.
Your data is stored under the `value` property and should always be accessed/modified through it.
#### Example
```ts
import {Persist} from 'ztimson/persist'
const theme = new Persist('theme.current', {default: 'os'});
console.log(theme.value); // Output: os
theme.value = 'light'; // Make sure you always use .value to access/modify data
location.reload(); // Simulate refresh
console.log(theme.value); // Output: light
```
#### Constructor
`Persist<T>(key: string, options?: PersistOptions)`
| Argument | Type | Description |
|-----------|--------------------------------------------------|-------------------------------------------------------------|
| `key` | `string` | Primary key value will be stored under |
| `options` | [`PersistOptions<T>`](../Home.md#persistoptions) | Configure using [PersistOptions](../Home.md#persistoptions) |
#### Properties
| Name | Type | Description |
|-----------|--------------------------------------------------|-------------------------------------------------------------|
| `key` | `string` | Primary key value will be stored under |
| `options` | [`PersistOptions<T>`](../Home.md#persistoptions) | Configure using [PersistOptions](../Home.md#persistoptions) |
| `value` | `T` | Current value |
#### Methods
##### clear
Delete value from storage
`clear(): void`
##### load
Load value from storage
`load(): void`
##### save
Save current value to storage
`save(): void`
##### watch
Register callback to listen for changes
`watch(fn: (value: T) => void): void`
#### Parameters
| Name | Type |
| :------ | :------ |
| `fn` | (`value`: `T`) => `any` |
##### toString
Return value as JSON string
`toString(): string`
###### Returns
`string` - Stringified JSON object
##### valueOf
Return current value
`valueOf(): T`
###### Returns
`T` - Current value
</details>
<details>
<summary>
<h3 id="decorators" style="display: inline">
Decorators
</h3>
</summary>
`persist(options?: {key?: string} & PersistOptions<T>)`
</details>
<details>
<summary>
<h3 id="types" style="display: inline">
Types
</h3>
</summary>
`PersistOptions<T>`
Configurable options to change persistence behavior
| Property | Type | Description |
|------------|-----------|----------------------------------------------------------------------------------------|
| `default?` | `T` | Default/Initial value if undefined |
| `storage?` | `Storage` | Storage implementation, defaults to LocalStorage. Can also be used with SessionStorage |
| `type?` | `any` | Force value to have \[proto\]type |
</details>
## License ## License
Copyright © 2023 Zakary Timson | Available under MIT Licensing Copyright © 2023 Zakary Timson | Available under MIT Licensing

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "persist", "name": "persist",
"version": "1.0.0", "version": "1.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "persist", "name": "persist",
"version": "1.0.0", "version": "1.0.1",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/jest": "^29.5.11", "@types/jest": "^29.5.11",

View File

@ -1,6 +1,6 @@
{ {
"name": "persist", "name": "persist",
"version": "1.0.0", "version": "1.0.1",
"description": "Sync variables with the local/session storage using proxy objects & decorators", "description": "Sync variables with the local/session storage using proxy objects & decorators",
"repository": "https://git.zakscode.com/ztimson/persistance", "repository": "https://git.zakscode.com/ztimson/persistance",
"author": "Zak Timson", "author": "Zak Timson",
@ -9,7 +9,7 @@
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"scripts": { "scripts": {
"build": "tsc && npm run build:docs", "build": "tsc && npm run build:docs",
"build:docs": "npx typedoc --readme none --plugin typedoc-plugin-markdown --entryDocument Home.md --out docs src/index.ts", "build:docs": "npx typedoc --readme none --out docs src/index.ts",
"test": "npx jest --verbose", "test": "npx jest --verbose",
"test:coverage": "npx jest --verbose --coverage", "test:coverage": "npx jest --verbose --coverage",
"watch": "npm run build && npx tsc --watch" "watch": "npm run build && npx tsc --watch"
@ -27,7 +27,6 @@
"jest-junit": "^16.0.0", "jest-junit": "^16.0.0",
"ts-jest": "^29.1.1", "ts-jest": "^29.1.1",
"typedoc": "^0.25.4", "typedoc": "^0.25.4",
"typedoc-plugin-markdown": "^3.17.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"files": [ "files": [

View File

@ -1,5 +1,5 @@
/** /**
* Configurations persistence behaviour * Configurable options to change persistence behavior
* *
* @group Options * @group Options
*/ */
@ -8,7 +8,7 @@ export type PersistOptions<T> = {
default?: T, default?: T,
/** Storage implementation, defaults to LocalStorage */ /** Storage implementation, defaults to LocalStorage */
storage?: Storage, storage?: Storage,
/** Force value to have prototype */ /** Force value to have [proto]type */
type?: any, type?: any,
} }
@ -27,12 +27,15 @@ export type PersistOptions<T> = {
* ``` * ```
*/ */
export class Persist<T> { export class Persist<T> {
/** Backend service to store data, must implement `Storage` interface */
private readonly storage!: Storage;
/** Listeners which should be notified on changes */
private watches: { [key: string]: Function } = {};
/** Private value field */ /** Private value field */
private _value!: T; private _value!: T;
/** Current value or default if undefined */ /** Current value or default if undefined */
get value(): T { return this._value !== undefined ? this._value : <T>this.options?.default; } get value(): T { return this._value !== undefined ? this._value : <T>this.options?.default; }
/** Set value with proxy object wrapper to sync future changes */ /** Set value with proxy object wrapper to sync future changes */
set value(v: T | undefined) { set value(v: T | undefined) {
if(v == null || typeof v != 'object') this._value = <T>v; if(v == null || typeof v != 'object') this._value = <T>v;
@ -56,13 +59,8 @@ export class Persist<T> {
this.save(); this.save();
} }
/** Where data gets physically stored */
private readonly storage!: Storage;
/** Listeners which should be notified on changes */
private watches: { [key: string]: Function } = {};
/** /**
* @param {string} key Unique key value will be stored under * @param {string} key Primary key value will be stored under
* @param {PersistOptions<T>} options Configure using {@link PersistOptions} * @param {PersistOptions<T>} options Configure using {@link PersistOptions}
*/ */
constructor(public readonly key: string, public options: PersistOptions<T> = {}) { constructor(public readonly key: string, public options: PersistOptions<T> = {}) {
@ -101,8 +99,8 @@ export class Persist<T> {
/** Return value as JSON string */ /** Return value as JSON string */
toString() { return JSON.stringify(this.value); } toString() { return JSON.stringify(this.value); }
/** Return raw value */ /** Return current value */
valueOf() { return this.value?.valueOf(); } valueOf() { return this.value; }
/** Notify listeners of change */ /** Notify listeners of change */
private notify(value: T) { private notify(value: T) {