as-model 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,129 @@
1
+ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
+ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { createNoStateModel } from "../validation";
4
+ import { generateNotifier } from "./notifier";
5
+ import { generateTunnelCreator, createUnInitializedUpdater, destroy } from "./tunnel";
6
+ function createInitializedUpdater(updater) {
7
+ var createTunnel = generateTunnelCreator(updater);
8
+ return {
9
+ notify: generateNotifier(updater),
10
+ createTunnel
11
+ };
12
+ }
13
+ function createUpdateFn(updater) {
14
+ return function update() {
15
+ var args = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
16
+ updater.mutate(function(u, effect) {
17
+ var _args_model;
18
+ var model = (_args_model = args.model) !== null && _args_model !== void 0 ? _args_model : u.model;
19
+ var initialState = "initialState" in args ? args.initialState : u.state;
20
+ var state = "state" in args ? args.state : u.state;
21
+ if (u.controlled) {
22
+ var instance = model(state);
23
+ return _object_spread_props(_object_spread({}, u), {
24
+ state,
25
+ instance,
26
+ model
27
+ });
28
+ }
29
+ if (u.isDestroyed) {
30
+ return u;
31
+ }
32
+ if (!u.initialized && !("initialState" in args)) {
33
+ throw new Error("Should update initialState first.");
34
+ }
35
+ if (!u.initialized) {
36
+ var instance1 = model(initialState);
37
+ var initializedUpdater = createInitializedUpdater(u);
38
+ return _object_spread(_object_spread_props(_object_spread({}, u), {
39
+ model,
40
+ state: initialState,
41
+ instance: instance1,
42
+ initialized: true
43
+ }), initializedUpdater);
44
+ }
45
+ if (Object.is(u.model, model) && Object.is(u.state, state)) {
46
+ return u;
47
+ }
48
+ var instance2 = model(state);
49
+ effect(function(up) {
50
+ up.notify({
51
+ type: null,
52
+ method: null,
53
+ prevInstance: u.instance,
54
+ instance: instance2,
55
+ prevState: u.state,
56
+ state
57
+ });
58
+ });
59
+ return _object_spread_props(_object_spread({}, u), {
60
+ state,
61
+ model,
62
+ instance: instance2,
63
+ initialized: true
64
+ });
65
+ });
66
+ };
67
+ }
68
+ var lazyModel = createNoStateModel();
69
+ function createUpdater(model) {
70
+ var config = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
71
+ var hasDefaultState = "state" in config;
72
+ var controlled = config.controlled, defaultState = config.state;
73
+ var defaultInstance = hasDefaultState ? model(defaultState) : lazyModel(void 0);
74
+ var unInitializedUpdater = createUnInitializedUpdater();
75
+ var updater = _object_spread({
76
+ sidePayload: void 0,
77
+ version: 0,
78
+ isDestroyed: false,
79
+ model,
80
+ instance: defaultInstance,
81
+ dispatch: null,
82
+ dispatches: [],
83
+ temporaryDispatches: [],
84
+ cacheMethods: {},
85
+ cacheFields: {},
86
+ state: defaultState,
87
+ initialized: hasDefaultState,
88
+ controlled: !!controlled,
89
+ isSubscribing: false,
90
+ config,
91
+ payload: function payload(setter) {
92
+ if (typeof setter === "function") {
93
+ updater.sidePayload = setter(updater.sidePayload);
94
+ }
95
+ return updater.sidePayload;
96
+ },
97
+ mutate: function mutate(callback) {
98
+ var effects = [];
99
+ var runEffects = function runEffects2(u) {
100
+ effects.forEach(function(e) {
101
+ return e(u);
102
+ });
103
+ };
104
+ var result = callback(updater, function(effectFn) {
105
+ return effects.push(effectFn);
106
+ });
107
+ if (updater === result) {
108
+ runEffects(result);
109
+ return updater;
110
+ }
111
+ Object.assign(updater, result);
112
+ runEffects(updater);
113
+ return updater;
114
+ },
115
+ update: function(args) {
116
+ },
117
+ destroy: function destroy1() {
118
+ destroy(updater);
119
+ }
120
+ }, unInitializedUpdater);
121
+ var initialized = createInitializedUpdater(updater);
122
+ Object.assign(updater, initialized, {
123
+ update: createUpdateFn(updater)
124
+ });
125
+ return updater;
126
+ }
127
+ export {
128
+ createUpdater
129
+ };
@@ -0,0 +1,121 @@
1
+ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
+ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
4
+ function defaultNotifyImplement(dispatches, action) {
5
+ dispatches.forEach(function(callback) {
6
+ callback(action);
7
+ });
8
+ }
9
+ function generateNotifier(updater) {
10
+ function pendAction(value) {
11
+ updater.mutate(function(u) {
12
+ var dispatching = u.dispatching;
13
+ if (!dispatching) {
14
+ var wrap = {
15
+ value
16
+ };
17
+ wrap.tail = wrap;
18
+ return _object_spread_props(_object_spread({}, u), {
19
+ dispatching: wrap
20
+ });
21
+ }
22
+ var tail = dispatching.tail;
23
+ if (!tail) {
24
+ return u;
25
+ }
26
+ var current = {
27
+ prev: tail,
28
+ value
29
+ };
30
+ tail.next = current;
31
+ dispatching.tail = current;
32
+ return _object_spread_props(_object_spread({}, u), {
33
+ dispatching
34
+ });
35
+ });
36
+ }
37
+ function unshiftAction() {
38
+ return updater.mutate(function(u) {
39
+ var dispatching = updater.dispatching;
40
+ if (!dispatching) {
41
+ return u;
42
+ }
43
+ var next = dispatching.next, tail = dispatching.tail;
44
+ if (tail === dispatching || !next) {
45
+ dispatching.tail = void 0;
46
+ return _object_spread_props(_object_spread({}, u), {
47
+ dispatching: void 0
48
+ });
49
+ }
50
+ next.prev = void 0;
51
+ var newFirst = next;
52
+ newFirst.tail = tail;
53
+ return _object_spread_props(_object_spread({}, u), {
54
+ dispatching: newFirst
55
+ });
56
+ }).dispatching;
57
+ }
58
+ function consumeTemporaries() {
59
+ var temporaryDispatches = updater.temporaryDispatches;
60
+ updater.mutate(function(u) {
61
+ return u.temporaryDispatches.length ? _object_spread_props(_object_spread({}, u), {
62
+ dispatches: _to_consumable_array(u.dispatches).concat(_to_consumable_array(u.temporaryDispatches)),
63
+ temporaryDispatches: []
64
+ }) : u;
65
+ });
66
+ var initializedAction = {
67
+ state: updater.state,
68
+ prevState: updater.state,
69
+ instance: updater.instance,
70
+ prevInstance: updater.instance,
71
+ type: null,
72
+ method: null
73
+ };
74
+ temporaryDispatches.forEach(function(call) {
75
+ call(initializedAction);
76
+ });
77
+ }
78
+ var config = updater.config;
79
+ return function notify(action) {
80
+ if (action == null) {
81
+ return;
82
+ }
83
+ var dispatching = updater.dispatching;
84
+ pendAction(action);
85
+ if (dispatching) {
86
+ return;
87
+ }
88
+ while (updater.dispatching) {
89
+ var wrap = updater.dispatching;
90
+ if (wrap) {
91
+ var dispatches = updater.dispatches;
92
+ var dispatchCallbacks = _to_consumable_array(dispatches);
93
+ try {
94
+ if (typeof config.batchNotify === "function" && dispatchCallbacks.length) {
95
+ config.batchNotify(dispatchCallbacks, wrap.value);
96
+ } else {
97
+ defaultNotifyImplement(dispatchCallbacks, wrap.value);
98
+ }
99
+ } catch (e) {
100
+ updater.mutate(function(u) {
101
+ return _object_spread_props(_object_spread({}, u), {
102
+ dispatching: void 0
103
+ });
104
+ });
105
+ throw e;
106
+ }
107
+ unshiftAction();
108
+ } else {
109
+ updater.mutate(function(u) {
110
+ return _object_spread_props(_object_spread({}, u), {
111
+ dispatching: void 0
112
+ });
113
+ });
114
+ }
115
+ }
116
+ consumeTemporaries();
117
+ };
118
+ }
119
+ export {
120
+ generateNotifier
121
+ };
@@ -0,0 +1,138 @@
1
+ import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
2
+ import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
3
+ import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
4
+ import { noop } from "../tools";
5
+ function createUnInitializedUpdater() {
6
+ return {
7
+ notify: function(a) {
8
+ },
9
+ createTunnel: function(dispatcher) {
10
+ return {
11
+ connect: noop,
12
+ disconnect: noop
13
+ };
14
+ }
15
+ };
16
+ }
17
+ function destroy(updater) {
18
+ function destroyDispatching() {
19
+ updater.mutate(function(u) {
20
+ var dispatching = u.dispatching;
21
+ if (!dispatching) {
22
+ return u;
23
+ }
24
+ var wrapper = dispatching;
25
+ while (wrapper) {
26
+ var next = wrapper.next;
27
+ wrapper.next = void 0;
28
+ wrapper.prev = void 0;
29
+ if (next) {
30
+ next.prev = void 0;
31
+ }
32
+ wrapper = next;
33
+ }
34
+ dispatching.tail = void 0;
35
+ return _object_spread_props(_object_spread({}, u), {
36
+ dispatching: void 0,
37
+ initialized: false
38
+ });
39
+ });
40
+ }
41
+ updater.mutate(function(u, effect) {
42
+ var destroyed = createUnInitializedUpdater();
43
+ effect(function() {
44
+ destroyDispatching();
45
+ });
46
+ return _object_spread_props(_object_spread({}, u, destroyed), {
47
+ sidePayload: void 0,
48
+ isDestroyed: true
49
+ });
50
+ });
51
+ }
52
+ function generateTunnelCreator(updater) {
53
+ function subscribe(dispatchFn) {
54
+ var dispatches = updater.dispatches, temporaryDispatches = updater.temporaryDispatches, isControlled = updater.controlled;
55
+ var copied = _to_consumable_array(dispatches).concat(_to_consumable_array(temporaryDispatches));
56
+ var exist = copied.indexOf(dispatchFn) >= 0;
57
+ if (exist) {
58
+ return updater.mutate(function(u) {
59
+ return _object_spread_props(_object_spread({}, u), {
60
+ isDestroyed: false
61
+ });
62
+ });
63
+ }
64
+ if (isControlled) {
65
+ return updater.mutate(function(u) {
66
+ return _object_spread_props(_object_spread({}, u), {
67
+ dispatches: [
68
+ dispatchFn
69
+ ],
70
+ isDestroyed: false
71
+ });
72
+ });
73
+ }
74
+ return updater.mutate(function(u, effect) {
75
+ var tds = u.temporaryDispatches, ds = u.dispatches;
76
+ var nextTds = _to_consumable_array(tds).concat([
77
+ dispatchFn
78
+ ]);
79
+ if (u.dispatching) {
80
+ return _object_spread_props(_object_spread({}, u), {
81
+ temporaryDispatches: nextTds,
82
+ isDestroyed: false
83
+ });
84
+ }
85
+ effect(function(up) {
86
+ var initializedAction = {
87
+ state: up.state,
88
+ prevState: up.state,
89
+ instance: up.instance,
90
+ prevInstance: up.instance,
91
+ type: null,
92
+ method: null
93
+ };
94
+ nextTds.forEach(function(td) {
95
+ td(initializedAction);
96
+ });
97
+ });
98
+ return _object_spread_props(_object_spread({}, u), {
99
+ temporaryDispatches: [],
100
+ dispatches: _to_consumable_array(ds).concat(_to_consumable_array(nextTds)),
101
+ isDestroyed: false
102
+ });
103
+ });
104
+ }
105
+ return function tunnel(dispatcher) {
106
+ function disconnect() {
107
+ updater.mutate(function(u) {
108
+ var ds = u.dispatches, tds = u.temporaryDispatches;
109
+ var nextDs = ds.filter(function(d) {
110
+ return d !== dispatcher;
111
+ });
112
+ var nextTds = tds.filter(function(d) {
113
+ return d !== dispatcher;
114
+ });
115
+ if (ds.length === nextDs.length && tds.length === nextTds.length) {
116
+ return u;
117
+ }
118
+ return _object_spread_props(_object_spread({}, u), {
119
+ dispatches: nextDs,
120
+ temporaryDispatches: nextTds
121
+ });
122
+ });
123
+ }
124
+ return {
125
+ connect: function connect() {
126
+ subscribe(dispatcher);
127
+ },
128
+ disconnect: function disconnect1() {
129
+ disconnect();
130
+ }
131
+ };
132
+ };
133
+ }
134
+ export {
135
+ createUnInitializedUpdater,
136
+ destroy,
137
+ generateTunnelCreator
138
+ };
File without changes
@@ -0,0 +1,25 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import { _ as _type_of } from "@swc/helpers/_/_type_of";
3
+ var noStateAModelKey = "no-state-a-model-key";
4
+ function createNoStateModel() {
5
+ return function noStateModel(state) {
6
+ return _define_property({}, noStateAModelKey, true);
7
+ };
8
+ }
9
+ function isInstanceFromNoStateModel(instance) {
10
+ if (instance == null) {
11
+ return false;
12
+ }
13
+ if ((typeof instance === "undefined" ? "undefined" : _type_of(instance)) !== "object") {
14
+ return false;
15
+ }
16
+ var ins = instance;
17
+ return !!ins[noStateAModelKey];
18
+ }
19
+ var validations = {
20
+ isInstanceFromNoStateModel
21
+ };
22
+ export {
23
+ createNoStateModel,
24
+ validations
25
+ };
package/index.d.ts ADDED
@@ -0,0 +1,163 @@
1
+ declare interface ModelInstance {
2
+ [key: string]: unknown;
3
+ [key: number]: unknown;
4
+ }
5
+
6
+ declare type ValidInstance<S, T extends ModelInstance> = {
7
+ [K in keyof T]: T[K] extends (...args: unknown[]) => S
8
+ ? T[K]
9
+ : T[K] extends (...args: unknown[]) => unknown
10
+ ? never
11
+ : T[K];
12
+ };
13
+
14
+ export type Model<S, T extends ModelInstance> = (
15
+ state: S
16
+ ) => ValidInstance<S, T>;
17
+
18
+ export type Action<S = any, T extends ModelInstance = ModelInstance> = {
19
+ type: null | string;
20
+ method: null | ((...args: any[]) => any);
21
+ params?: any[];
22
+ state: S;
23
+ prevState?: S;
24
+ instance: T;
25
+ prevInstance?: T;
26
+ };
27
+
28
+ declare type Dispatch = (action: Action) => unknown;
29
+
30
+ export interface Key<S = any, T extends ModelInstance = any>
31
+ extends Model<S, T> {
32
+ (s: S): T;
33
+ source: Model<S, T>;
34
+ modelKeyIdentifier: () => boolean;
35
+ [k: string]: any;
36
+ }
37
+
38
+ export interface Config {
39
+ controlled?: boolean;
40
+ batchNotify?: (
41
+ listeners: ((action: Action) => void)[],
42
+ action: Action
43
+ ) => void;
44
+ }
45
+
46
+ /** createStore * */
47
+
48
+ export interface KeyWrapper<S = any, T extends ModelInstance = any> {
49
+ key: Key<S, T>;
50
+ }
51
+
52
+ export interface Store<S = any, T extends ModelInstance = any>
53
+ extends KeyWrapper<S, T> {
54
+ subscribe: (dispatcher: Dispatch) => () => void;
55
+ getInstance: () => T;
56
+ update: (args?: { model?: Model<S, T>; state?: S }) => void;
57
+ destroy: () => void;
58
+ payload: <R>(
59
+ callback?: (payload: R | undefined) => R | undefined
60
+ ) => R | undefined;
61
+ isDestroyed: () => boolean;
62
+ }
63
+
64
+ export function createStore<S, T extends ModelInstance, D extends S>(
65
+ model: Model<S, T> | Key<S, T>,
66
+ state?: D
67
+ ): Store<S, T>;
68
+
69
+ /** createKey * */
70
+
71
+ export interface ModelKey<S = any, T extends ModelInstance = any>
72
+ extends Key<S, T> {
73
+ (s: S): T;
74
+ createStore: <D extends S>(state?: D) => Store<S, T>;
75
+ }
76
+
77
+ // eslint-disable-next-line @typescript-eslint/naming-convention
78
+ export interface createKey {
79
+ <S, T extends ModelInstance, D extends S>(
80
+ model: Model<S, T>,
81
+ state?: D
82
+ ): ModelKey<S, T>;
83
+ isModelKey: <S, T extends ModelInstance>(
84
+ data: unknown
85
+ ) => data is ModelKey<S, T>;
86
+ }
87
+
88
+ /** createStores * */
89
+
90
+ export interface StoreCollection {
91
+ find: <S, T extends ModelInstance>(
92
+ key: Key<S, T> | KeyWrapper<S, T>
93
+ ) => Store<S, T> | null;
94
+ update: (...keys: (ModelKey | KeyWrapper)[]) => void;
95
+ destroy: () => void;
96
+ }
97
+
98
+ export function createStores(
99
+ ...modelKeys: (ModelKey | KeyWrapper)[]
100
+ ): StoreCollection;
101
+
102
+ /** model API * */
103
+
104
+ export interface ModelUsage<S, T extends ModelInstance> {
105
+ (s: S): ValidInstance<S, T>;
106
+ createKey: (state?: S) => ModelKey<S, T>;
107
+ createStore: (state?: S) => Store<S, T>;
108
+ }
109
+
110
+ declare type FieldStructure<R = any> = {
111
+ callback: () => R;
112
+ deps: unknown[] | undefined;
113
+ identifier: (d: unknown) => d is FieldStructure<R>;
114
+ value: R;
115
+ get: () => R;
116
+ };
117
+
118
+ declare type MethodStructure<
119
+ R extends (...args: any[]) => any = (...args: any[]) => any
120
+ > = R & {
121
+ identifier: (d: unknown) => d is MethodStructure;
122
+ };
123
+
124
+ // eslint-disable-next-line @typescript-eslint/naming-convention
125
+ export interface model {
126
+ <S, T extends ModelInstance>(modelFn: Model<S, T>): ModelUsage<S, T>;
127
+ createField: <R extends () => any>(
128
+ callback: R,
129
+ deps?: unknown[]
130
+ ) => FieldStructure<ReturnType<R>>;
131
+ createMethod: <R extends (...args: any[]) => any = (...args: any[]) => any>(
132
+ method: R
133
+ ) => MethodStructure<R>;
134
+ }
135
+
136
+ /** createSignal * */
137
+
138
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
139
+ declare interface SignalStore<S = any, T extends ModelInstance = any>
140
+ extends KeyWrapper<S, T> {
141
+ subscribe: (dispatcher: Dispatch) => () => void;
142
+ getSignal: () => {
143
+ (): T;
144
+ startStatistics: () => void;
145
+ stopStatistics: () => void;
146
+ subscribe: (dispatcher: Dispatch) => () => void;
147
+ payload: <R>(
148
+ callback?: (payload: R | undefined) => R | undefined
149
+ ) => R | undefined;
150
+ };
151
+ }
152
+
153
+ export declare function createSignal<S, T extends ModelInstance>(
154
+ store: Store<S, T>
155
+ ): SignalStore<S, T>;
156
+
157
+ /** config * */
158
+ export declare function config(configuration: Config): {
159
+ createStore: typeof createStore;
160
+ createKey: typeof createKey;
161
+ createStores: typeof createStores;
162
+ model: typeof model;
163
+ };
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "private": false,
3
+ "name": "as-model",
4
+ "version": "0.0.1",
5
+ "description": "This is a model state management tool",
6
+ "license": "MIT",
7
+ "author": "Jimmy.Harding",
8
+ "homepage": "https://github.com/filefoxper/a-model",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/filefoxper/a-model"
12
+ },
13
+ "main": "dist/index.js",
14
+ "module": "esm/index.js",
15
+ "files": [
16
+ "dist",
17
+ "esm",
18
+ "index.d.ts"
19
+ ],
20
+ "scripts": {
21
+ "build": "node ./build.js",
22
+ "docs": "docsify serve ./docs",
23
+ "lint": "eslint src --fix --ext .ts,.tsx ",
24
+ "lint-init": "eslint --init",
25
+ "test": "jest --coverage"
26
+ },
27
+ "typings": "index.d.ts",
28
+ "devDependencies": {
29
+ "@types/jest": "^29.5.14",
30
+ "@babel/cli": "^7.25.9",
31
+ "@babel/core": "^7.26.0",
32
+ "@babel/eslint-parser": "^7.25.9",
33
+ "@babel/plugin-transform-runtime": "^7.25.9",
34
+ "@babel/preset-env": "^7.26.0",
35
+ "@babel/preset-typescript": "^7.26.0",
36
+ "@babel/runtime": "^7.26.0",
37
+ "esbuild": "^0.25.0",
38
+ "esbuild-plugin-es5": "2.1.1",
39
+ "eslint": "^8.49.0",
40
+ "eslint-config-airbnb": "^19.0.4",
41
+ "eslint-config-airbnb-typescript": "^17.1.0",
42
+ "eslint-config-prettier": "^9.0.0",
43
+ "eslint-import-resolver-typescript": "^3.6.0",
44
+ "eslint-plugin-import": "^2.28.1",
45
+ "eslint-plugin-jsx-a11y": "^6.7.1",
46
+ "eslint-plugin-prettier": "^5.0.0",
47
+ "eslint-plugin-react": "^7.33.2",
48
+ "eslint-plugin-react-hooks": "^4.6.0",
49
+ "eslint-plugin-unused-imports": "^2.0.0",
50
+ "eslint-webpack-plugin": "^4.0.1",
51
+ "prettier": "^3.0.3",
52
+ "prettier-eslint": "^15.0.1",
53
+ "prettier-eslint-cli": "^7.1.0",
54
+ "typescript": "^4.9.5",
55
+ "babel-jest": "29.7.0",
56
+ "jest": "29.7.0",
57
+ "jest-environment-jsdom": "29.7.0",
58
+ "ts-jest": "^29.2.5",
59
+ "ts-node": "^10.8.1",
60
+ "pmnps": "^4.5.3",
61
+ "@pmnps/plugin-publish": "4.5.0"
62
+ },
63
+ "keywords": [
64
+ "model",
65
+ "state",
66
+ "state-management",
67
+ "typescript"
68
+ ]
69
+ }