mobx-keystone-asyncstore
Advanced tools
Comparing version 0.4.0 to 0.4.1
@@ -16,6 +16,7 @@ "use strict"; | ||
const mobx_1 = require("mobx"); | ||
let id = -1; | ||
// We cannot explicitly define a return type here | ||
// since it's generated | ||
// eslint-disable-next-line | ||
function createAsyncContainer(ItemModel, asyncProps) { | ||
const { name, ttl = Infinity, failstateTtl = 5000 } = asyncProps; | ||
id++; | ||
const AsyncContainerModel = mobx_keystone_1.Model({ | ||
@@ -49,3 +50,3 @@ id: mobx_keystone_1.prop(), | ||
} | ||
return undefined || this._value; | ||
return this._value; | ||
} | ||
@@ -52,0 +53,0 @@ get shouldFetch() { |
@@ -1,3 +0,2 @@ | ||
import { AnyModel, ModelClass, ModelProps, _Model } from "mobx-keystone"; | ||
import { IAsyncContainer } from "./AsyncContainer"; | ||
import { AnyModel, ModelClass, ModelProps } from "mobx-keystone"; | ||
export interface AsyncStoreOptions<T> { | ||
@@ -13,3 +12,3 @@ name?: string; | ||
} | ||
export declare function AsyncStore<AModel extends ModelClass<AnyModel>, AProps extends AsyncStoreOptions<InstanceType<AModel>>, TProps extends ModelProps>(ItemModel: AModel, asyncProps: AProps, modelProps?: TProps): _Model<import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
export declare function AsyncStore<AModel extends ModelClass<AnyModel>, AProps extends AsyncStoreOptions<InstanceType<AModel>>, TProps extends ModelProps>(ItemModel: AModel, asyncProps: AProps, modelProps?: TProps): import("mobx-keystone")._Model<import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
containers: import("mobx-keystone").OptionalModelProp<Record<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
@@ -30,3 +29,3 @@ id: import("mobx-keystone").MaybeOptionalModelProp<string, string>; | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>, Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>, Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
id: import("mobx-keystone").MaybeOptionalModelProp<string, string>; | ||
@@ -46,3 +45,3 @@ _value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>>; | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>>; | ||
}>, { | ||
@@ -64,3 +63,3 @@ containers?: Record<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>> | null | undefined; | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>> | null | undefined; | ||
}, import("mobx-keystone").ModelPropsToInstanceData<{ | ||
@@ -82,3 +81,3 @@ containers: import("mobx-keystone").OptionalModelProp<Record<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>, Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>, Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
id: import("mobx-keystone").MaybeOptionalModelProp<string, string>; | ||
@@ -98,3 +97,3 @@ _value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>>; | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>>; | ||
}>, { | ||
@@ -116,3 +115,3 @@ containers?: Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>> | null | undefined; | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>> | null | undefined; | ||
}> & Pick<import("mobx-keystone").ModelPropsToInstanceData<{ | ||
@@ -134,3 +133,3 @@ containers: import("mobx-keystone").OptionalModelProp<Record<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>, Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>, Map<string, import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
id: import("mobx-keystone").MaybeOptionalModelProp<string, string>; | ||
@@ -150,3 +149,3 @@ _value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>>; | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>>; | ||
}>, "containers"> & IBaseAsyncStore<import("mobx-keystone").BaseModel<import("mobx-keystone").ModelPropsToPropsData<{ | ||
@@ -167,3 +166,3 @@ id: import("mobx-keystone").MaybeOptionalModelProp<string, string>; | ||
_value: import("mobx-keystone").MaybeOptionalModelProp<any, any>; | ||
}>, "id" | "_value"> & IAsyncContainer<InstanceType<AModel>>>, TProps>; | ||
}>, "id" | "_value"> & import("./AsyncContainer").IAsyncContainer<InstanceType<AModel>>>, TProps>; | ||
export interface IBaseAsyncStore<T> { | ||
@@ -170,0 +169,0 @@ containers: Map<string, T>; |
@@ -28,2 +28,5 @@ "use strict"; | ||
let id = -1; | ||
// We cannot explicitly define a return type here | ||
// since it's generated | ||
// eslint-disable-next-line | ||
function AsyncStore(ItemModel, asyncProps, modelProps = {}) { | ||
@@ -73,7 +76,9 @@ id++; | ||
? yield fetchOne.call(this, id) | ||
: yield fetchMany.call(this, [id]); | ||
ct.setValue(item); | ||
: // We do know that we have fetchMany here | ||
// eslint-disable-next-line | ||
yield fetchMany.call(this, [id]); | ||
ct === null || ct === void 0 ? void 0 : ct.setValue(item); | ||
} | ||
catch (e) { | ||
ct.setFailstate(e); | ||
ct === null || ct === void 0 ? void 0 : ct.setFailstate(e); | ||
} | ||
@@ -80,0 +85,0 @@ this.setReady(); |
{ | ||
"name": "mobx-keystone-asyncstore", | ||
"version": "0.4.0", | ||
"version": "0.4.1", | ||
"author": "Marcus Ekwall <marcus.ekwall@gmail.com>", | ||
"description": "An opinionated asynchronous store and container implementation for mobx-keystone.", | ||
"license": "MIT", | ||
@@ -10,2 +11,9 @@ "main": "dist/index.js", | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/mekwall/mobx-keystone-asyncstore.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/mekwall/mobx-keystone-asyncstore/issues" | ||
}, | ||
"scripts": { | ||
@@ -15,3 +23,6 @@ "test": "jest", | ||
"build": "tsc -b tsconfig.build.json", | ||
"publish": "yarn build && yarn npm publish" | ||
"lint": "eslint", | ||
"lint-staged": "lint-staged", | ||
"validate": "yarn lint && tsc --skipLibCheck --noEmit -p tsconfig.json", | ||
"release": "semantic-release" | ||
}, | ||
@@ -28,10 +39,24 @@ "peerDependencies": { | ||
"@babel/preset-typescript": "^7.10.4", | ||
"@semantic-release/changelog": "^5.0.1", | ||
"@semantic-release/commit-analyzer": "^8.0.1", | ||
"@semantic-release/git": "^9.0.0", | ||
"@semantic-release/npm": "^7.0.5", | ||
"@semantic-release/release-notes-generator": "^9.0.1", | ||
"@types/debug": "^4.1.5", | ||
"@types/jest": "^26.0.7", | ||
"@types/node": "^14.0.27", | ||
"@typescript-eslint/eslint-plugin": "^3.7.1", | ||
"@typescript-eslint/parser": "^3.7.1", | ||
"@yarnpkg/pnpify": "^2.1.0", | ||
"commitlint": "^9.1.0", | ||
"conventional-changelog-conventionalcommits": "^4.3.0", | ||
"cross-env": "^7.0.2", | ||
"eslint": "^7.5.0", | ||
"husky": "^4.2.5", | ||
"jest": "^26.1.0", | ||
"lint-staged": "^10.2.11", | ||
"mobx": "^5.15.4", | ||
"mobx-keystone": "^0.45.0", | ||
"prettier": "^2.0.5", | ||
"semantic-release": "^17.1.1", | ||
"ts-node-dev": "^1.0.0-pre.56", | ||
@@ -38,0 +63,0 @@ "typescript": "^3.9.7" |
119
README.md
# mobx-keystone-asyncstore | ||
![](https://github.com/mekwall/mobx-keystone-asyncstore/workflows/.github/workflows/main.yml/badge.svg) | ||
_An opinionated asynchronous store and container implementation for [mobx-keystone](https://mobx-keystone.js.org/)._ | ||
> Warning: This library is under development and not yet stable. Use with caution. | ||
[![license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/mekwall/mobx-keystone-asyncstore/blob/master/LICENSE) | ||
[![npm](https://img.shields.io/npm/v/mobx-keystone-asyncstore.svg?style=flat-square&logo=npm)](https://www.npmjs.com/package/mobx-keystone-asyncstore) | ||
![types](https://img.shields.io/npm/types/mobx-keystone-asyncstore.svg?style=flat-square&logo=typescript) | ||
[![build](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fmekwall%2Fmobx-keystone-asyncstore%2Fbadge%3Fref%3Dmaster&label=build&style=flat-square)](https://actions-badge.atrox.dev/mekwall/mobx-keystone-asyncstore/goto?ref=master) | ||
[![coverage](https://img.shields.io/codecov/c/github/mekwall/mobx-keystone-asyncstore?style=flat-square)](https://codecov.io/github/mekwall/mobx-keystone-asyncstore?branch=master) | ||
[![quality](https://img.shields.io/lgtm/grade/javascript/github/mekwall/mobx-keystone-asyncstore?style=flat-square])](https://lgtm.com/projects/g/mekwall/mobx-keystone-asyncstore/?mode=list) | ||
> ⚠️**WARNING**: This library is under development and not yet considered stable. Use with caution as breaking changes to the API may be introduced until reaching v1. | ||
## Introduction | ||
One of the most common challenges when implementing a store solution is how to handle asynchronous data sets. mobx-keystone-asyncstore aims to simplify this by allowing you to create powerful asynchronous stores with just a few lines of code. An mobx-keystone-asyncstore implements the most common fetch patterns and support fetch queues, fail states and time to live out of the box. | ||
Let's look at a simple implementation of a TodoStore: | ||
```ts | ||
import axios from "axios"; | ||
import { when } from "mobx"; | ||
import { model, modelAction, Model, tProps } from "mobx-keystone"; | ||
import { AsyncStore } from "mobx-keystone-asyncstore"; | ||
// Create main model | ||
@model("models/TodoItem") | ||
class TodoItem extends Model({ | ||
id: tProps(types.string), | ||
task: tProps(types.string), | ||
done: tProps(types.boolean, false) | ||
}){ | ||
@modelAction | ||
public toggleDone() { | ||
this.done = !!this.done; | ||
} | ||
}; | ||
// Create async store | ||
const storeName = "stores/TodoStore"; | ||
@model(storeName) | ||
class TodoStore extends AsyncStore(TodoItem, { | ||
{ name: storeName }, | ||
// Logic to fetch one item | ||
async fetchOne(id: string) { | ||
const res = await axios.get(`/todos/${id}`); | ||
return new TodoItem(res.data); | ||
}, | ||
// Logic to fetch many items | ||
async fetchMany(ids: string[]) { | ||
const res = await axios.get(`/todos`, { ids }); | ||
return res.data.response.map((d) => new TodoItem(d)); | ||
}, | ||
// Logic to fetch all items | ||
async fetchAll() { | ||
const res = await axios.get(`/todos/all`); | ||
return res.data.response.map((d) => new TodoItem(d)); | ||
}, | ||
}, { | ||
// Add additional model props for the store | ||
isDirty: tProp(types.boolean, true) | ||
}) { | ||
@modelAction | ||
public setDirty(isDirty = true) { | ||
this.isDirty = isDirty; | ||
} | ||
// Add additional methods for the store | ||
@modelAction | ||
public addTodo(task: TodoItem) { | ||
// Create container that will contain our task | ||
const container = this.createAsyncContainer(task.id); | ||
// Add task to container value | ||
container.setValue(task); | ||
// Add container to store | ||
this.containers.set(task.id, task); | ||
// Set the store as dirty | ||
this.setDirty(); | ||
// Let's return the container so it may be used | ||
return container; | ||
} | ||
// Method to save all our todos | ||
async saveToDataBase() { | ||
if (this.isDirty) { | ||
const res = await axios.post(`/todos`, this.values); | ||
if (res.status === 200) { | ||
this.setDirty(false); | ||
} | ||
} | ||
} | ||
} | ||
// Create store instance | ||
const todoStore = new TodoStore({}); | ||
// Ask the store to return container with id 'foo' | ||
const container = todoStore.get("foo"); | ||
// Wait for the container to be ready to be consumed | ||
when( | ||
() => container.isReady, | ||
() => { | ||
const todo = container.value; | ||
// todo is an instance of TodoItem | ||
todo.toggleDone(); | ||
} | ||
); | ||
// Add a new todo to the store | ||
todoStore.addTodo( | ||
new TodoItem({ | ||
id: "bar", | ||
task: "Do this thing as well" | ||
}) | ||
); | ||
// Use our custom save method | ||
todoStore.saveToDb(); | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
45129
608
0
121
0
29