Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/huang2002/hstorage
A storage lib.
https://github.com/huang2002/hstorage
3h localstorage sessionstorage storage store
Last synced: 5 days ago
JSON representation
A storage lib.
- Host: GitHub
- URL: https://github.com/huang2002/hstorage
- Owner: huang2002
- License: mit
- Created: 2019-08-09T11:13:37.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2019-08-09T11:31:28.000Z (over 5 years ago)
- Last Synced: 2024-12-15T10:12:01.757Z (about 1 month ago)
- Topics: 3h, localstorage, sessionstorage, storage, store
- Language: TypeScript
- Size: 33.2 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# hstorage
> A storage lib.
## TOC
- [Introduction](#introduction)
- [Usage](#usage)
- [API Reference](#api-reference)
- [Links](#links)## Introduction
`hstorage` is a storage lib which has a custom type system and is rather lightweight(<10KB after minification WITHOUT zipping). With your store declared, type checking and conflict detecting will be available out of the box.
## Usage
### npm
1. Use npm to install it as a dependency:
```bash
npm install hstorage
```2. Import the exports of this lib:
```js
import { /* ... */ } from "hstorage";
// or
const { /* ... */ } = require("hstorage");
```3. Use them in your code.
### CDN
1. Include one of the following script tags in your HTML file:
via jsdelivr:
```html
```or via unpkg:
```html
```2. Access the APIs via the `HS` global.
```js
const { /* ... */ } = HS;
```If you want a specified version, just replace `latest` with that in the url. By the way, it is recommended to use a specified version in production.
For more information about these two CDN sites, visit [www.jsdelivr.com](https://www.jsdelivr.com) and [unpkg.com](https://unpkg.com).
## API Reference
(The API reference is written in [TypeScript](https://www.typescriptlang.org/).)
```ts
/**
* @desc The type of storage-like objects.
*/
interface StorageLike {/**
* @desc Get the item value by giving the key to it.
*/
getItem(key: string): string | null;/**
* @desc Set the item value by giving the key to it.
*/
setItem(key: string, value: string): void;}
/**
* @desc The type of store options. (These are all
* partial properties on store instances, so you can
* refer to the property details for more information.)
*/
interface StoreOptions {
defaultValue?: T | null;
type?: Type | null;
delay?: number;
storage?: StorageLike;
lazyLoad?: boolean;
strictLoad?: boolean;
secure?: boolean;
autoFix?: boolean;
onInvalid?: StoreInvalidCallback | null;
onConflict?: StoreConflictCallback | null;
pathSeparator?: string;
}/**
* @desc The class for store instances.
*/
class Store {/**
* @desc The defaults of store options.
*/
static defaults: StoreOptions;/**
* @desc The constructor which accepts a required name and optional options.
*/
constructor(name: string, options?: StoreOptions);/**
* @desc The name which is used as the key to the store.
*/
name: string;/**
* @desc The default value of the store. If this is omitted but the `type` property
* is given, `type.defaultValue` will be adopted.
*
*/
defaultValue: T | null;/**
* @desc The type of the store. (See the `Type` interface and built-in types below.)
* If this is omitted but the `defaultValue` is given, an inferred type generated by
* `inferType`(see below) will be adopted.
*/
type: Type | null;/**
* @desc The delay of saving in milliseconds. (If zero, save synchronously.)
*/
delay: number;/**
* @desc The storage to use.
* @default localStorage
*/
storage: StorageLike;/**
* @desc Whether not to load immediately when the store is being created.
* @default false
*/
readonly lazyLoad: boolean;/**
* @desc Whether to do type checking while loading the store from storage.
* @default true
*/
strictLoad: boolean;/**
* @desc Whether to check conflicts while saving.
* @default true
*/
secure: boolean;/**
* @desc Whether to try to fix invalid value automatically.
* @default true
*/
autoFix: boolean;/**
* @desc The invalidation callback. (If not given, errors will be thrown instead.)
* @param paths The invalid property paths. (Path `[]` means the root.)
*/
onInvalid: ((this: Store, paths: string[][]) => void) | null;/**
* @desc The conflict callback. (If not given, errors will be thrown instead.)
* @param newSource The current source in the storage.
* @param oldSource The copy of the old source in the storage.
* @example
* ```js
* onConflict(newSource, oldSource) {
* if (youWantTheNewSource) {
* this.load(newSource);
* } else {
* this.storage.setItem(this.name, oldSource);
* this.save();
* }
* }
* ```
*/
onConflict: ((this: Store, newSource: string | null, oldSource: string | null) => void) | null;/**
* @desc The path separator to use.
* @default '.'
*/
pathSeparator: string;/**
* @desc Manually save the store. (synchronously)
* @returns Whether the saving is successful. (`false` if conflict occurs
* or no `storage` given.)
*/
save(): boolean;/**
* @desc Reset the specific value.
* @param selector A path string or a path array.
* @returns Whether the reset is successful. (`false` if the default value can't be found.)
* @example
* ```js
* store.reset('foo.bar');
* store.reset(['foo', 'bar']);
* ```
*/
reset(selector: string | string[]): boolean;/**
* @desc Load the store from source.
* @param source The source string. If omitted, read the source from `storage`.
* @returns Whether the loading is successful. (`false` both on invalidation
* if it can't be fixed and no storage presence.)
*/
load(source?: string | null): boolean;/**
* @desc Check whether the sources conflict.
* @returns `true` if conflict; `false` otherwise.
*/
checkConflict(): boolean;/**
* @desc Get the specific store value by giving a property path string or
* a path array. Invoke it without arguments to get the whole store value.
*/
get(path?: string | string[]): unknown;/**
* @desc Set the specific value by giving a path and a new value or
* an updating callback which accepts the old value and returns a new one.
* @returns Whether the operation is successful. (`false` on invalidation if it can't fixed.)
*/
set(path: string | string[], patch: unknown | (this: Store, oldValue: unknown) => unknown): boolean;}
/**
* @desc The type of validating results.
*/
interface ValidatingResult {/**
* @desc Whether the value is valid.
*/
valid: boolean;/**
* @desc The path of invalid properties if there is any.
*/
paths?: string[][];}
/**
* @desc The type of type class instances.
*/
interface Type {/**
* @desc The default value.
*/
defaultValue: T;/**
* @desc Validate the given result.
*/
validate(value: unknown): ValidatingResult;}
/**
* @desc Turn an object into a map of corresponding type class instances.
*/
type Types = {
[K in Extract]: Type;
};/**
* @desc The type class of any types. (always valid)
*/
class Any implements Type {
constructor(defaultValue?: any);
defaultValue: any;
validate(): ValidatingResult;
}/**
* @desc Create an any type instance.
*/
function any(defaultValue?: any): Any;/**
* @desc The type class of booleans.
*/
class Boolean implements Type {
defaultValue: boolean;
constructor(defaultValue?: boolean);
validate(value: unknown): ValidatingResult;
}/**
* @desc Create a boolean type instance.
*/
function boolean(defaultValue?: boolean): Boolean;/**
* @desc The type of string options. (See property details.)
*/
interface StringOptions {
defaultValue?: string;
minLength?: number;
maxLength?: number;
pattern?: RegExp | null;
}/**
* @desc The type class of strings.
*/
class String implements Type {static defaults: StringOptions;
constructor(options?: StringOptions);
defaultValue: string;
/**
* @desc The minimum string length.
* @default 0
*/
minLength: number;/**
* @desc The maximum string length.
* @default Infinity
*/
maxLength: number;/**
* @desc The string pattern. (`null` means any pattern.)
*/
pattern: RegExp | null;validate(value: unknown): ValidatingResult;
}
/**
* @desc Create a string type instance.
*/
function string(options?: StringOptions): String;/**
* @desc The type of number options. (See property details.)
*/
interface NumberOptions {
defaultValue?: number;
min?: number;
max?: number;
integer?: boolean;
}/**
* @desc The type class of numbers.
*/
class Number implements Type {static defaults: NumberOptions;
constructor(options?: NumberOptions);
defaultValue: number;
/**
* @desc The minimum limit.
* @default -Infinity
*/
min: number;/**
* @desc The maximum limit.
* @default Infinity
*/
max: number;/**
* @desc Whether the number must be an integer.
* @default false
*/
integer: boolean;validate(value: unknown): ValidatingResult;
}
/**
* @desc Create a number type instance.
*/
function number(options?: NumberOptions | undefined): Number;/**
* @desc The type of nullable options. (See property details.)
*/
interface NullableOptions {
defaultValue?: T;
null?: boolean;
undefined?: boolean;
}/**
* @desc The type class of nullable value.
*/
class Nullable implements Type {static defaults: NullableOptions;
constructor(options?: NullableOptions);
defaultValue: T;
/**
* @desc Whether `null` is acceptable.
* @default true
*/
null: boolean;/**
* @desc Whether `undefined` is acceptable.
* @default true
*/
undefined: boolean;validate(value: unknown): ValidatingResult;
}
/**
* @desc Create a nullable type instance.
*/
function nullable:
(options?: NullableOptions): Nullable;/**
* @desc The type class of dictionaries.
*/
class Dictionary implements Type {/**
* @desc The property types. (`null` or `undefined` means no limit.)
* @example
* ```js
* dictionary.types = {
* foo: HS.string(),
* bar: HS.number(),
* };
* ```
*/
readonly types?: Types | null;constructor(types?: Types | null);
/**
* @desc The default value. (If not provided, one will be created from `types`.)
*/
defaultValue: T;validate(value: unknown): ValidatingResult;
}
/**
* @desc Create a dictionary type instance.
*/
function dictionary(types?: Types | null): Dictionary;/**
* @desc The type of list options. (See property details.)
*/
interface ListOptions {
defaultValue?: T[];
type: Type;
}/**
* @desc The type class of lists.
*/
class List implements Type {static defaults: ListOptions;
constructor(options?: ListOptions);
defaultValue: T[];
/**
* @desc The type of list elements.
* @default Any
*/
type: Type;validate(value: unknown): ValidatingResult;
}
/**
* @desc Create a list type instance.
*/
function list(options?: ListOptions): List;/**
* @desc The type of union options. (See property details.)
*/
interface UnionOptions {
defaultValue?: T;
types: Type[];
}/**
* @desc The type class of union.
*/
class Union implements Type {constructor(options?: UnionOptions);
/**
* @desc The default value. (If not provided, one will be created from `types`.)
*/
defaultValue: T;/**
* @desc The types included in the union.
*/
types: Type[];validate(value: unknown): ValidatingResult;
}
/**
* @desc Create a union type instance.
*/
function union(options?: UnionOptions): Union;/**
* @desc Get the type nested in the given type by giving the path to it.
* (Its ancestors must be dictionary types.)
*/
function getTypeByPath(type: Type, path: string[]): Type;/**
* @desc Infer type from the given value.
*/
function inferType(value: unknown): Type;```
## Links
- [Contributing Guide](./CONTRIBUTING.md)
- [Changelog](./CHANGELOG.md)
- [License (MIT)](./LICENSE)