native-document 1.0.95 → 1.0.98

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.
Files changed (43) hide show
  1. package/{src/devtools/hrm → devtools}/ComponentRegistry.js +2 -2
  2. package/devtools/index.js +8 -0
  3. package/{src/devtools/plugin.js → devtools/plugin/dev-tools-plugin.js} +2 -2
  4. package/{src/devtools/hrm/nd-vite-hot-reload.js → devtools/transformers/nd-vite-devtools.js} +16 -6
  5. package/devtools/transformers/src/transformComponentForHrm.js +74 -0
  6. package/devtools/transformers/src/transformJsFile.js +9 -0
  7. package/devtools/transformers/src/utils.js +79 -0
  8. package/devtools/widget/Widget.js +48 -0
  9. package/devtools/widget/widget.css +81 -0
  10. package/devtools/widget.js +23 -0
  11. package/dist/native-document.components.min.js +1922 -1277
  12. package/dist/native-document.dev.js +1985 -1401
  13. package/dist/native-document.dev.js.map +1 -1
  14. package/dist/native-document.devtools.min.js +1 -1
  15. package/dist/native-document.min.js +1 -1
  16. package/docs/cache.md +1 -1
  17. package/docs/core-concepts.md +1 -1
  18. package/docs/native-document-element.md +51 -15
  19. package/docs/observables.md +310 -306
  20. package/docs/state-management.md +198 -193
  21. package/package.json +1 -1
  22. package/readme.md +1 -1
  23. package/src/core/data/ObservableChecker.js +2 -0
  24. package/src/core/data/ObservableItem.js +97 -0
  25. package/src/core/data/ObservableObject.js +182 -0
  26. package/src/core/data/Store.js +364 -34
  27. package/src/core/data/observable-helpers/object.js +2 -166
  28. package/src/core/utils/formatters.js +91 -0
  29. package/src/core/utils/localstorage.js +57 -0
  30. package/src/core/utils/validator.js +0 -2
  31. package/src/devtools.js +9 -0
  32. package/src/fetch/NativeFetch.js +5 -2
  33. package/types/observable.d.ts +71 -15
  34. package/types/plugins-manager.d.ts +1 -1
  35. package/types/store.d.ts +33 -6
  36. package/hrm.js +0 -7
  37. package/src/devtools/app/App.js +0 -66
  38. package/src/devtools/app/app.css +0 -0
  39. package/src/devtools/hrm/transformComponent.js +0 -129
  40. package/src/devtools/index.js +0 -18
  41. package/src/devtools/widget/DevToolsWidget.js +0 -26
  42. /package/{src/devtools/hrm → devtools/transformers/templates}/hrm.hook.template.js +0 -0
  43. /package/{src/devtools/hrm → devtools/transformers/templates}/hrm.orbservable.hook.template.js +0 -0
@@ -1,137 +1,10 @@
1
1
  import Validator from "../../utils/validator";
2
2
  import {Observable} from "../Observable";
3
+ import {ObservableObject} from "../ObservableObject";
3
4
 
4
- const ObservableObjectValue = function(data) {
5
- const result = {};
6
- for(const key in data) {
7
- const dataItem = data[key];
8
- if(Validator.isObservable(dataItem)) {
9
- let value = dataItem.val();
10
- if(Array.isArray(value)) {
11
- value = value.map(item => {
12
- if(Validator.isObservable(item)) {
13
- return item.val();
14
- }
15
- if(Validator.isProxy(item)) {
16
- return item.$value;
17
- }
18
- return item;
19
- });
20
- }
21
- result[key] = value;
22
- } else if(Validator.isProxy(dataItem)) {
23
- result[key] = dataItem.$value;
24
- } else {
25
- result[key] = dataItem;
26
- }
27
- }
28
- return result;
29
- };
30
-
31
- const ObservableGet = function(target, property) {
32
- const item = target[property];
33
- if(Validator.isObservable(item)) {
34
- return item.val();
35
- }
36
- if(Validator.isProxy(item)) {
37
- return item.$value;
38
- }
39
- return item;
40
- };
41
5
 
42
- /**
43
- * Creates an observable proxy for an object where each property becomes an observable.
44
- * Properties can be accessed directly or via getter methods.
45
- *
46
- * @param {Object} initialValue - Initial object value
47
- * @param {Object|null} [configs=null] - Configuration options
48
- * // @param {boolean} [configs.propagation=true] - Whether changes propagate to parent
49
- * @param {boolean} [configs.deep=false] - Whether to make nested objects observable
50
- * @param {boolean} [configs.reset=false] - Whether to enable reset() method
51
- * @returns {ObservableProxy} A proxy where each property is an observable
52
- * @example
53
- * const user = Observable.init({
54
- * name: 'John',
55
- * age: 25,
56
- * address: { city: 'NYC' }
57
- * }, { deep: true });
58
- *
59
- * user.name.val(); // 'John'
60
- * user.name.set('Jane');
61
- * user.name = 'Jane X'
62
- * user.age.subscribe(val => console.log('Age:', val));
63
- */
64
6
  Observable.init = function(initialValue, configs = null) {
65
- const data = {};
66
- for(const key in initialValue) {
67
- const itemValue = initialValue[key];
68
- if(Array.isArray(itemValue)) {
69
- if(configs?.deep !== false) {
70
- const mappedItemValue = itemValue.map(item => {
71
- if(Validator.isJson(item)) {
72
- return Observable.json(item, configs);
73
- }
74
- if(Validator.isArray(item)) {
75
- return Observable.array(item, configs);
76
- }
77
- return Observable(item, configs);
78
- });
79
- data[key] = Observable.array(mappedItemValue, configs);
80
- continue;
81
- }
82
- data[key] = Observable.array(itemValue, configs);
83
- continue;
84
- }
85
- if(Validator.isObservable(itemValue) || Validator.isProxy(itemValue)) {
86
- data[key] = itemValue;
87
- continue;
88
- }
89
- data[key] = Observable(itemValue, configs);
90
- }
91
-
92
- const $reset = () => {
93
- for(const key in data) {
94
- const item = data[key];
95
- item.reset();
96
- }
97
- }
98
-
99
- const $val = () => ObservableObjectValue(data);
100
-
101
- const $clone = () => Observable.init($val(), configs);
102
-
103
- const $updateWith = (values) => {
104
- Observable.update(proxy, values);
105
- };
106
-
107
- const $get = (key) => ObservableGet(data, key);
108
-
109
- const proxy = new Proxy(data, {
110
- get(target, property) {
111
- if(property === '__isProxy__') { return true; }
112
- if(property === '$value') { return $val() }
113
- if(property === 'get' || property === '$get') { return $get; }
114
- if(property === 'val' || property === '$val') { return $val; }
115
- if(property === 'set' || property === '$set' || property === '$updateWith') { return $updateWith; }
116
- if(property === 'observables' || property === '$observables') { return Object.values(target); }
117
- if(property === 'keys'|| property === '$keys') { return Object.keys(initialValue); }
118
- if(property === 'clone' || property === '$clone') { return $clone; }
119
- if(property === 'reset') { return $reset; }
120
- if(property === 'configs') { return configs; }
121
- return target[property];
122
- },
123
- set(target, prop, newValue) {
124
- if(target[prop] !== undefined) {
125
- Validator.isObservable(newValue)
126
- ? target[prop].set(newValue.val())
127
- : target[prop].set(newValue);
128
- return true;
129
- }
130
- return true;
131
- }
132
- });
133
-
134
- return proxy;
7
+ return new ObservableObject(initialValue, configs)
135
8
  };
136
9
 
137
10
  /**
@@ -166,42 +39,5 @@ Observable.value = function(data) {
166
39
  return data;
167
40
  };
168
41
 
169
-
170
- Observable.update = function($target, newData) {
171
- const data = Validator.isProxy(newData) ? newData.$value : newData;
172
- const configs = $target.configs;
173
-
174
- for(const key in data) {
175
- const targetItem = $target[key];
176
- const newValueOrigin = newData[key];
177
- const newValue = data[key];
178
-
179
- if(Validator.isObservable(targetItem)) {
180
- if(Validator.isArray(newValue)) {
181
- const firstElementFromOriginalValue = newValueOrigin.at(0);
182
- if(Validator.isObservable(firstElementFromOriginalValue) || Validator.isProxy(firstElementFromOriginalValue)) {
183
- const newValues = newValue.map(item => {
184
- if(Validator.isProxy(firstElementFromOriginalValue)) {
185
- return Observable.init(item, configs);
186
- }
187
- return Observable(item, configs);
188
- });
189
- targetItem.set(newValues);
190
- continue;
191
- }
192
- targetItem.set([...newValue]);
193
- continue;
194
- }
195
- targetItem.set(newValue);
196
- continue;
197
- }
198
- if(Validator.isProxy(targetItem)) {
199
- Observable.update(targetItem, newValue);
200
- continue;
201
- }
202
- $target[key] = newValue;
203
- }
204
- };
205
-
206
42
  Observable.object = Observable.init;
207
43
  Observable.json = Observable.init;
@@ -0,0 +1,91 @@
1
+ const $parseDateParts = (value, locale) => {
2
+ const d = new Date(value);
3
+ return {
4
+ d,
5
+ parts: new Intl.DateTimeFormat(locale, {
6
+ year: 'numeric',
7
+ month: 'long',
8
+ day: '2-digit',
9
+ hour: '2-digit',
10
+ minute: '2-digit',
11
+ second: '2-digit',
12
+ }).formatToParts(d).reduce((acc, { type, value }) => {
13
+ acc[type] = value;
14
+ return acc;
15
+ }, {})
16
+ };
17
+ };
18
+
19
+ const $applyDatePattern = (pattern, d, parts) => {
20
+ const pad = n => String(n).padStart(2, '0');
21
+ return pattern
22
+ .replace('YYYY', parts.year)
23
+ .replace('YY', parts.year.slice(-2))
24
+ .replace('MMMM', parts.month)
25
+ .replace('MMM', parts.month.slice(0, 3))
26
+ .replace('MM', pad(d.getMonth() + 1))
27
+ .replace('DD', pad(d.getDate()))
28
+ .replace('D', d.getDate())
29
+ .replace('HH', parts.hour)
30
+ .replace('mm', parts.minute)
31
+ .replace('ss', parts.second);
32
+ };
33
+
34
+ export const Formatters = {
35
+
36
+ currency: (value, locale, { currency = 'XOF', notation, minimumFractionDigits, maximumFractionDigits } = {}) =>
37
+ new Intl.NumberFormat(locale, {
38
+ style: 'currency',
39
+ currency,
40
+ notation,
41
+ minimumFractionDigits,
42
+ maximumFractionDigits
43
+ }).format(value),
44
+
45
+ number: (value, locale, { notation, minimumFractionDigits, maximumFractionDigits } = {}) =>
46
+ new Intl.NumberFormat(locale, {
47
+ notation,
48
+ minimumFractionDigits,
49
+ maximumFractionDigits
50
+ }).format(value),
51
+
52
+ percent: (value, locale, { decimals = 1 } = {}) =>
53
+ new Intl.NumberFormat(locale, {
54
+ style: 'percent',
55
+ maximumFractionDigits: decimals
56
+ }).format(value),
57
+
58
+ date: (value, locale, { format, dateStyle = 'long' } = {}) => {
59
+ if (format) {
60
+ const { d, parts } = $parseDateParts(value, locale);
61
+ return $applyDatePattern(format, d, parts);
62
+ }
63
+ return new Intl.DateTimeFormat(locale, { dateStyle }).format(new Date(value));
64
+ },
65
+
66
+ time: (value, locale, { format, hour = '2-digit', minute = '2-digit', second } = {}) => {
67
+ if (format) {
68
+ const { d, parts } = $parseDateParts(value, locale);
69
+ return $applyDatePattern(format, d, parts);
70
+ }
71
+ return new Intl.DateTimeFormat(locale, { hour, minute, second }).format(new Date(value));
72
+ },
73
+
74
+ datetime: (value, locale, { format, dateStyle = 'long', hour = '2-digit', minute = '2-digit', second } = {}) => {
75
+ if (format) {
76
+ const { d, parts } = $parseDateParts(value, locale);
77
+ return $applyDatePattern(format, d, parts);
78
+ }
79
+ return new Intl.DateTimeFormat(locale, { dateStyle, hour, minute, second }).format(new Date(value));
80
+ },
81
+
82
+ relative: (value, locale, { unit = 'day', numeric = 'auto' } = {}) => {
83
+ const diff = Math.round((value - Date.now()) / (1000 * 60 * 60 * 24));
84
+ return new Intl.RelativeTimeFormat(locale, { numeric }).format(diff, unit);
85
+ },
86
+
87
+ plural: (value, locale, { singular, plural } = {}) => {
88
+ const rule = new Intl.PluralRules(locale).select(value);
89
+ return `${value} ${rule === 'one' ? singular : plural}`;
90
+ },
91
+ };
@@ -0,0 +1,57 @@
1
+ import NativeDocumentError from "../errors/NativeDocumentError";
2
+
3
+ export const LocalStorage = {
4
+ getJson(key) {
5
+ let value = localStorage.getItem(key);
6
+ try {
7
+ return JSON.parse(value);
8
+ } catch (e) {
9
+ throw new NativeDocumentError('invalid_json:'+key);
10
+ }
11
+ },
12
+ getNumber(key) {
13
+ return Number(this.get(key));
14
+ },
15
+ getBool(key) {
16
+ const value = this.get(key);
17
+ return value === 'true' || value === '1';
18
+ },
19
+ setJson(key, value) {
20
+ localStorage.setItem(key, JSON.stringify(value));
21
+ },
22
+ setBool(key, value) {
23
+ localStorage.setItem(key, value ? 'true' : 'false');
24
+ },
25
+ get(key, defaultValue = null) {
26
+ return localStorage.getItem(key) || defaultValue;
27
+ },
28
+ set(key, value) {
29
+ return localStorage.setItem(key, value);
30
+ },
31
+ remove(key) {
32
+ localStorage.removeItem(key);
33
+ },
34
+ has(key) {
35
+ return localStorage.getItem(key) != null;
36
+ }
37
+ }
38
+
39
+ export const $getFromStorage = (key, value) => {
40
+ if(!LocalStorage.has(key)) {
41
+ return value;
42
+ }
43
+ switch (typeof value) {
44
+ case 'object': return LocalStorage.getJson(key) ?? value;
45
+ case 'boolean': return LocalStorage.getBool(key) ?? value;
46
+ case 'number': return LocalStorage.getNumber(key) ?? value;
47
+ default: return LocalStorage.get(key, value) ?? value;
48
+ }
49
+ };
50
+
51
+ export const $saveToStorage = (value) => {
52
+ switch (typeof value) {
53
+ case 'object': return LocalStorage.setJson;
54
+ case 'boolean': return LocalStorage.setBool;
55
+ default: return LocalStorage.set;
56
+ }
57
+ };
@@ -1,9 +1,7 @@
1
- import ObservableItem from "../data/ObservableItem";
2
1
  import DebugManager from "./debug-manager";
3
2
  import NativeDocumentError from "../errors/NativeDocumentError";
4
3
  import ObservableChecker from "../data/ObservableChecker";
5
4
  import {NDElement} from "../wrappers/NDElement";
6
- import TemplateBinding from "../wrappers/TemplateBinding";
7
5
 
8
6
  const COMMON_NODE_TYPES = {
9
7
  ELEMENT: 1,
@@ -0,0 +1,9 @@
1
+ import Devtools from './devtools';
2
+ import NdViteDevtools from "../devtools/transformers/nd-vite-devtools.js";
3
+ import transformComponentForHrm from "../devtools/transformers/src/transformComponentForHrm.js";
4
+
5
+ export {
6
+ transformComponentForHrm,
7
+ NdViteDevtools,
8
+ Devtools,
9
+ };
@@ -36,11 +36,14 @@ export default function NativeFetch($baseUrl) {
36
36
  configs.body = params;
37
37
  }
38
38
  else {
39
- configs.headers['Content-Type'] = 'application/json';
40
39
  if(method !== 'GET') {
40
+ configs.headers['Content-Type'] = 'application/json';
41
41
  configs.body = JSON.stringify(params);
42
42
  } else {
43
- configs.params = params;
43
+ const queryString = new URLSearchParams(params).toString();
44
+ if (queryString) {
45
+ endpoint = endpoint + (endpoint.includes('?') ? '&' : '?') + queryString;
46
+ }
44
47
  }
45
48
  }
46
49
  }
@@ -1,7 +1,47 @@
1
- import {FilterResult, PredicateMap} from "./filters/types";
1
+ import {FilterResult, PredicateMap} from "./filters";
2
2
 
3
3
  export type Unsubscribe = () => void;
4
4
 
5
+ export type FormatType = 'currency' | 'number' | 'percent' | 'date' | 'time' | 'datetime' | 'relative' | 'plural';
6
+
7
+ export interface FormatOptions {
8
+ // currency
9
+ currency?: string;
10
+ notation?: 'standard' | 'scientific' | 'engineering' | 'compact';
11
+ minimumFractionDigits?: number;
12
+ maximumFractionDigits?: number;
13
+ // percent
14
+ decimals?: number;
15
+ // date / datetime
16
+ dateStyle?: 'full' | 'long' | 'medium' | 'short';
17
+ format?: string;
18
+ // time / datetime
19
+ hour?: '2-digit' | 'numeric';
20
+ minute?: '2-digit' | 'numeric';
21
+ second?: '2-digit' | 'numeric';
22
+ // relative
23
+ unit?: 'day' | 'week' | 'month' | 'year' | 'hour' | 'minute' | 'second';
24
+ numeric?: 'always' | 'auto';
25
+ // plural
26
+ singular?: string;
27
+ plural?: string;
28
+ }
29
+
30
+ export interface FormattersStatic {
31
+ currency(value: number, locale: string, options?: FormatOptions): string;
32
+ number(value: number, locale: string, options?: FormatOptions): string;
33
+ percent(value: number, locale: string, options?: FormatOptions): string;
34
+ date(value: Date | number, locale: string, options?: FormatOptions): string;
35
+ time(value: Date | number, locale: string, options?: FormatOptions): string;
36
+ datetime(value: Date | number, locale: string, options?: FormatOptions): string;
37
+ relative(value: Date | number, locale: string, options?: FormatOptions): string;
38
+ plural(value: number, locale: string, options?: FormatOptions): string;
39
+ [key: string]: (value: any, locale: string, options?: FormatOptions) => string;
40
+ }
41
+
42
+ export declare const Formatters: FormattersStatic;
43
+
44
+
5
45
  // Observable system type definitions
6
46
  export interface ObservableItem<T = any> {
7
47
  readonly $currentValue: T;
@@ -22,12 +62,21 @@ export interface ObservableItem<T = any> {
22
62
  on(value: T, callback: ObservableItem<boolean> | ((isActive: boolean) => void)): () => void;
23
63
 
24
64
  check<U>(callback: (value: T) => U): ObservableChecker<U>;
25
- get<U>(callback: (value: T) => U): ObservableChecker<U>;
65
+ transform<U>(callback: (value: T) => U): ObservableChecker<U>;
66
+ is<U>(callback: (value: T) => U): ObservableChecker<U>;
67
+ select<U>(callback: (value: T) => U): ObservableChecker<U>;
68
+ pluck<U>(callback: (value: T) => U): ObservableChecker<U>;
69
+ format(type: FormatType | ((value: T) => string), options?: FormatOptions): ObservableItem<string>;
70
+ get(key: string | number): any;
26
71
  when(value: T): ObservableWhen<T>;
27
72
  off(value: T, callback?: Function): void;
28
73
  once(predicate: T | ((value: T) => boolean), callback: (value: T) => void): void;
29
74
  onCleanup(callback: () => void): void;
30
75
  intercept(callback: (newValue: T, currentValue: T) => T | undefined): this;
76
+ persist(key: string, options?: {
77
+ get?: (value: any) => T;
78
+ set?: (value: T) => any;
79
+ }): this;
31
80
  disconnectAll(): void;
32
81
 
33
82
  toString(): string;
@@ -103,35 +152,42 @@ export interface ObservableArray<T> extends ObservableItem<T[]> {
103
152
  whereEvery<K extends keyof T>(fields: K[], filter: FilterResult<T[K]>): ObservableArray<T>;
104
153
  }
105
154
 
106
- export type ObservableProxy<T extends Record<string, any>> = {
155
+ export type ObservableObject<T extends Record<string, any>> = ObservableItem<T> & {
156
+ readonly __$isObservableObject: true;
107
157
  readonly __isProxy__: true;
108
- readonly $value: T;
158
+ readonly $observables: { [K in keyof T]: ObservableItem<T[K]> };
109
159
  readonly configs: ObservableConfig | null;
160
+
161
+ $load(initialValue: Partial<T>): void;
110
162
  $val(): T;
111
163
  val(): T;
112
- $get(key: string): any;
113
164
  get(key: string): any;
114
- $clone(): ObservableProxy<T>;
115
- clone(): ObservableProxy<T>;
116
- $updateWith(values: Partial<T>): void;
117
- $set(values: Partial<T>): void;
165
+ $get(key: string): any;
118
166
  set(values: Partial<T>): void;
167
+ $set(values: Partial<T>): void;
168
+ $updateWith(values: Partial<T>): void;
169
+ update(values: Partial<T>): void;
119
170
  reset(): void;
171
+ clone(): ObservableObject<T>;
172
+ $clone(): ObservableObject<T>;
120
173
  keys(): string[];
174
+ $keys(): string[];
175
+ observables(): ObservableItem<any>[];
121
176
  } & {
122
177
  [K in keyof T]: T[K] extends (infer U)[]
123
178
  ? ObservableArray<U>
124
179
  : T[K] extends Record<string, any>
125
- ? ObservableProxy<T[K]>
180
+ ? ObservableObject<T[K]>
126
181
  : ObservableItem<T[K]>;
127
182
  };
128
183
 
184
+
129
185
  export interface BatchFunction<TArgs extends any[] = any[], TReturn = any> {
130
186
  (...args: TArgs): TReturn;
131
187
  readonly $observer: ObservableItem<number>;
132
188
  }
133
189
 
134
- export type ValidComputedDependencies = Array<ObservableItem | ObservableArray<any> | ObservableChecker | ObservableProxy<any>>;
190
+ export type ValidComputedDependencies = Array<ObservableItem | ObservableArray<any> | ObservableChecker | ObservableObject<any>>;
135
191
 
136
192
  export interface AutoCleanupOptions {
137
193
  interval?: number;
@@ -148,9 +204,9 @@ export interface ObservableStatic {
148
204
  <T>(value: T, configs?: ObservableConfig | null): ObservableItem<T>;
149
205
  array<T>(target: T[] | null, configs?: ObservableConfig | null): ObservableArray<T>;
150
206
 
151
- init<T extends Record<string, any>>(value: T, configs?: ObservableConfig | null): ObservableProxy<T>;
152
- object<T extends Record<string, any>>(value: T, configs?: ObservableConfig | null): ObservableProxy<T>;
153
- json<T extends Record<string, any>>(value: T, configs?: ObservableConfig | null): ObservableProxy<T>;
207
+ init<T extends Record<string, any>>(value: T, configs?: ObservableConfig | null): ObservableObject<T>;
208
+ object<T extends Record<string, any>>(value: T, configs?: ObservableConfig | null): ObservableObject<T>;
209
+ json<T extends Record<string, any>>(value: T, configs?: ObservableConfig | null): ObservableObject<T>;
154
210
 
155
211
  computed<T>(callback: () => T, dependencies?: ValidComputedDependencies | BatchFunction): ObservableItem<T>;
156
212
  computed<T>(callback: () => T, batchFunction?: BatchFunction): ObservableItem<T>;
@@ -165,5 +221,5 @@ export interface ObservableStatic {
165
221
  getById(id: number): ObservableItem | null;
166
222
  cleanup(observable: ObservableItem): void;
167
223
  autoCleanup(enable?: boolean, options?: AutoCleanupOptions): void;
168
- arrayOfObject<T extends Record<string, any>>(data: T[]): ObservableProxy<T>[];
224
+ arrayOfObject<T extends Record<string, any>>(data: T[]): ObservableObject<T>[];
169
225
  }
@@ -1,4 +1,4 @@
1
- import {NDElement} from "./elements";
1
+ import {NDElement} from "./nd-element";
2
2
  import {ObservableItem} from "./observable";
3
3
  import { Map} from "./polyfill";
4
4
 
package/types/store.d.ts CHANGED
@@ -1,12 +1,39 @@
1
- // Store system type definitions
2
1
  import { ObservableItem } from './observable';
3
- import {Set} from "./polyfill";
2
+ import { Set } from "./polyfill";
3
+
4
+ export type StoreGroupInstance = StoreStatic & {
5
+ readonly $name: string;
6
+ };
4
7
 
5
8
  export interface StoreStatic {
6
9
  create<T>(name: string, value: T): ObservableItem<T>;
7
- use<T>(name: string): ObservableItem<T>;
8
- follow<T>(name: string): ObservableItem<T>;
10
+ createResettable<T>(name: string, value: T): ObservableItem<T>;
11
+ createComposed<T>(
12
+ name: string,
13
+ computation: () => T,
14
+ dependencies: (string | ObservableItem<any>)[]
15
+ ): ObservableItem<T>;
16
+ createPersistent<T>(name: string, value: T, localStorageKey?: string): ObservableItem<T>;
17
+ createPersistentResettable<T>(name: string, value: T, localStorageKey?: string): ObservableItem<T>;
18
+
19
+ has(name: string): boolean;
9
20
  get<T>(name: string): ObservableItem<T> | null;
10
- getWithSubscribers<T>(name: string): { observer: ObservableItem<T>; subscribers: Set<ObservableItem<T>> } | undefined;
21
+ getWithSubscribers<T>(name: string): {
22
+ observer: ObservableItem<T>;
23
+ subscribers: Set<ObservableItem<T>>;
24
+ } | null;
25
+
26
+ use<T>(name: string): ObservableItem<T>;
27
+ follow<T>(name: string): Readonly<ObservableItem<T>>;
28
+
29
+ reset(name: string): void;
11
30
  delete(name: string): void;
12
- }
31
+
32
+ group(callback: (group: StoreGroupInstance) => void): StoreGroupInstance;
33
+ group(name: string, callback: (group: StoreGroupInstance) => void): StoreGroupInstance;
34
+
35
+ readonly [key: string]: ObservableItem<any> | unknown;
36
+ }
37
+
38
+ export declare const StoreFactory: () => StoreStatic;
39
+ export declare const Store: StoreStatic;
package/hrm.js DELETED
@@ -1,7 +0,0 @@
1
- import NdViteHotReload from "./src/devtools/hrm/nd-vite-hot-reload.js";
2
- import transformComponent from "./src/devtools/hrm/transformComponent.js";
3
-
4
- export {
5
- transformComponent,
6
- NdViteHotReload,
7
- };
@@ -1,66 +0,0 @@
1
- import {Div} from "../../../elements";
2
- import DevToolsWidget from "../../devtools/widget/DevToolsWidget";
3
-
4
- export default function App() {
5
-
6
-
7
- return Div(
8
- Div({ class: 'devtools-app-panel-wrapper pin-to-right' }, [
9
- DevToolsWidget,
10
- Div({ class: 'devtools-app-panel' }),
11
- Div('Gogo Panel')
12
- ]),
13
- ).nd.closedShadow(`
14
- .devtools-app-panel-wrapper {
15
- position: fixed;
16
- width: 0px;
17
- background: red;
18
- animate: .25s linear;
19
- }
20
- .devtools-app-panel-wrapper.pin-to-right {
21
- right: 0;
22
- top: 0;
23
- bottom: 0;
24
- }
25
- .devtools-app-panel-widget {
26
- position: fixed;
27
- background: rgba(0, 0, 0, 0.8);
28
- backdrop-filter: blur(5px);
29
- padding: 2px;
30
- width: 150px;
31
- height: 30px;
32
- border-radius: 5px;
33
- border: 1px solid black;
34
- z-index: 10000009;
35
- color: white;
36
- cursor: pointer;
37
- transform: translate(-50%, -50%);
38
- display: flex;
39
- justify-content: space-between;
40
- align-items: stretch;
41
- align-content: center;
42
- }
43
- .widget-button {
44
- width: 30px;
45
- padding: 2px;
46
- background: rgba(0, 0, 0, 0.8);
47
- border: 1px solid black;
48
- display: flex;
49
- justify-content: center;
50
- align-items: center;
51
- align-content: center;
52
- color: white;
53
- border-radius: 5px;
54
- cursor: pointer;
55
- font-size: .9rem;
56
- }
57
- .widget-label {
58
- font-weight: bold;
59
- font-size: 1.5rem;
60
- flex: 1;
61
- display: flex;
62
- justify-content: center;
63
- align-items: center;
64
- }
65
- `);
66
- }
File without changes