bindra 2.0.0

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 (48) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +229 -0
  4. package/dist/core/Container.d.ts +88 -0
  5. package/dist/core/Container.d.ts.map +1 -0
  6. package/dist/core/Container.js +185 -0
  7. package/dist/core/Container.js.map +1 -0
  8. package/dist/core/DataSource.d.ts +272 -0
  9. package/dist/core/DataSource.d.ts.map +1 -0
  10. package/dist/core/DataSource.js +903 -0
  11. package/dist/core/DataSource.js.map +1 -0
  12. package/dist/core/Dispatcher.d.ts +6 -0
  13. package/dist/core/Dispatcher.d.ts.map +1 -0
  14. package/dist/core/Dispatcher.js +44 -0
  15. package/dist/core/Dispatcher.js.map +1 -0
  16. package/dist/core/EventEmitter.d.ts +11 -0
  17. package/dist/core/EventEmitter.d.ts.map +1 -0
  18. package/dist/core/EventEmitter.js +34 -0
  19. package/dist/core/EventEmitter.js.map +1 -0
  20. package/dist/core/MiddlewareManager.d.ts +47 -0
  21. package/dist/core/MiddlewareManager.d.ts.map +1 -0
  22. package/dist/core/MiddlewareManager.js +86 -0
  23. package/dist/core/MiddlewareManager.js.map +1 -0
  24. package/dist/core/Observable.d.ts +12 -0
  25. package/dist/core/Observable.d.ts.map +1 -0
  26. package/dist/core/Observable.js +43 -0
  27. package/dist/core/Observable.js.map +1 -0
  28. package/dist/core/errors.d.ts +124 -0
  29. package/dist/core/errors.d.ts.map +1 -0
  30. package/dist/core/errors.js +149 -0
  31. package/dist/core/errors.js.map +1 -0
  32. package/dist/core/validation.d.ts +100 -0
  33. package/dist/core/validation.d.ts.map +1 -0
  34. package/dist/core/validation.js +217 -0
  35. package/dist/core/validation.js.map +1 -0
  36. package/dist/examples.d.ts +52 -0
  37. package/dist/examples.d.ts.map +1 -0
  38. package/dist/examples.js +242 -0
  39. package/dist/examples.js.map +1 -0
  40. package/dist/index.d.ts +13 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +14 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/utils/performance.d.ts +49 -0
  45. package/dist/utils/performance.d.ts.map +1 -0
  46. package/dist/utils/performance.js +94 -0
  47. package/dist/utils/performance.js.map +1 -0
  48. package/package.json +64 -0
@@ -0,0 +1,242 @@
1
+ /**
2
+ * Bindra TypeScript Usage Examples
3
+ *
4
+ * This file demonstrates how to use Bindra with TypeScript for type-safe
5
+ * reactive data management.
6
+ */
7
+ import { DataSource, createSignal, reactive } from './index';
8
+ // Create a typed DataSource
9
+ const usersDS = new DataSource({
10
+ data: [
11
+ { id: 1, name: 'Alice', email: 'alice@example.com', age: 25, isActive: true },
12
+ { id: 2, name: 'Bob', email: 'bob@example.com', age: 30, isActive: true },
13
+ { id: 3, name: 'Charlie', email: 'charlie@example.com', age: 35, isActive: false }
14
+ ]
15
+ });
16
+ // Subscribe to changes with type safety
17
+ usersDS.currentRecord.subscribe((user) => {
18
+ if (user) {
19
+ console.log(`Current user: ${user.name} (${user.email})`);
20
+ // TypeScript knows all properties of user
21
+ console.log(`Age: ${user.age}`);
22
+ }
23
+ });
24
+ // Navigate through records
25
+ usersDS.next();
26
+ usersDS.prev();
27
+ usersDS.goto(0);
28
+ // ============================================================================
29
+ // Example 2: CRUD Operations with Type Safety
30
+ // ============================================================================
31
+ async function crudExample() {
32
+ // Create - TypeScript enforces the User interface
33
+ const newUser = await usersDS.create({
34
+ id: 4,
35
+ name: 'David',
36
+ email: 'david@example.com',
37
+ age: 28
38
+ });
39
+ console.log('Created:', newUser);
40
+ // Update - Partial<User> allows partial updates
41
+ const updated = await usersDS.update(1, {
42
+ age: 26,
43
+ isActive: false
44
+ });
45
+ console.log('Updated:', updated);
46
+ // Query with type-safe filter
47
+ const activeUsers = await usersDS.query({
48
+ filter: (user) => user.isActive === true,
49
+ sort: 'age',
50
+ limit: 10
51
+ });
52
+ console.log('Active users:', activeUsers);
53
+ // Delete
54
+ const deleted = await usersDS.delete(4);
55
+ console.log('Deleted:', deleted);
56
+ }
57
+ // ============================================================================
58
+ // Example 3: Event Handling with Types
59
+ // ============================================================================
60
+ // Type-safe event handlers
61
+ usersDS.on('created', (user) => {
62
+ console.log('New user created:', user.name);
63
+ });
64
+ usersDS.on('updated', (user) => {
65
+ console.log('User updated:', user.name);
66
+ });
67
+ usersDS.on('deleted', (user) => {
68
+ console.log('User deleted:', user.name);
69
+ });
70
+ usersDS.on('dataChanged', (data) => {
71
+ console.log('Data changed, total users:', data?.length ?? 0);
72
+ });
73
+ // ============================================================================
74
+ // Example 4: Middleware with Type Safety
75
+ // ============================================================================
76
+ // Type-safe before middleware
77
+ usersDS.middleware.useBefore('create', async ({ record }) => {
78
+ const user = record;
79
+ // Validation
80
+ if (!user.name || user.name.length < 2) {
81
+ throw new Error('Name must be at least 2 characters');
82
+ }
83
+ if (!user.email || !user.email.includes('@')) {
84
+ throw new Error('Invalid email address');
85
+ }
86
+ if (user.age && (user.age < 0 || user.age > 150)) {
87
+ throw new Error('Age must be between 0 and 150');
88
+ }
89
+ console.log('Validation passed for:', user.name);
90
+ });
91
+ // Type-safe after middleware
92
+ usersDS.middleware.useAfter('create', async ({ record }) => {
93
+ const user = record;
94
+ console.log(`Welcome email sent to ${user.email}`);
95
+ // Could trigger analytics, logging, etc.
96
+ });
97
+ // ============================================================================
98
+ // Example 5: Signals and Reactive State
99
+ // ============================================================================
100
+ // Create typed signals
101
+ const counter = createSignal(0);
102
+ const message = createSignal('Hello');
103
+ // Subscribe with type safety
104
+ counter.subscribe((value) => {
105
+ console.log('Counter:', value);
106
+ });
107
+ message.subscribe((value) => {
108
+ console.log('Message:', value);
109
+ });
110
+ // Update signals
111
+ counter.set(10);
112
+ message.set('Hello, TypeScript!');
113
+ const appState = reactive({
114
+ theme: 'light',
115
+ user: {
116
+ name: 'Alice',
117
+ preferences: {
118
+ notifications: true,
119
+ language: 'en'
120
+ }
121
+ },
122
+ items: ['item1', 'item2']
123
+ }, (prop, newValue, oldValue) => {
124
+ console.log(`State changed: ${String(prop)}`);
125
+ console.log(` Old: ${JSON.stringify(oldValue)}`);
126
+ console.log(` New: ${JSON.stringify(newValue)}`);
127
+ });
128
+ // Deep reactivity - all changes are tracked
129
+ appState.theme = 'dark';
130
+ appState.user.name = 'Bob';
131
+ appState.user.preferences.notifications = false;
132
+ appState.items.push('item3');
133
+ const productsConfig = {
134
+ url: 'https://api.example.com/products'
135
+ };
136
+ const productsDS = new DataSource(productsConfig);
137
+ // Remote operations work the same way
138
+ async function remoteExample() {
139
+ // Fetch from remote API
140
+ const products = await productsDS.query({
141
+ filter: { category: 'electronics', inStock: true },
142
+ sort: 'price',
143
+ limit: 20
144
+ });
145
+ console.log('Products:', products);
146
+ // Create on remote
147
+ const newProduct = await productsDS.create({
148
+ name: 'New Laptop',
149
+ price: 999,
150
+ category: 'electronics',
151
+ inStock: true
152
+ });
153
+ console.log('Created product:', newProduct);
154
+ }
155
+ // ============================================================================
156
+ // Example 8: Advanced Pattern - Form Binding
157
+ // ============================================================================
158
+ class UserForm {
159
+ constructor(dataSource) {
160
+ this.unsubscribers = [];
161
+ this.ds = dataSource;
162
+ this.bindToCurrentRecord();
163
+ }
164
+ bindToCurrentRecord() {
165
+ // Subscribe to current record changes
166
+ const unsub = this.ds.currentRecord.subscribe((user) => {
167
+ if (user) {
168
+ this.populateForm(user);
169
+ }
170
+ });
171
+ this.unsubscribers.push(unsub);
172
+ }
173
+ populateForm(user) {
174
+ // Update form fields
175
+ console.log('Populating form with:', user);
176
+ // In real app: update DOM elements
177
+ }
178
+ async save(formData) {
179
+ const currentUser = this.ds.currentRecord.get();
180
+ if (currentUser) {
181
+ await this.ds.update(currentUser.id, formData);
182
+ }
183
+ else {
184
+ await this.ds.create(formData);
185
+ }
186
+ }
187
+ cleanup() {
188
+ this.unsubscribers.forEach(unsub => unsub());
189
+ }
190
+ }
191
+ // Usage
192
+ // @ts-ignore - Unused variable for documentation purposes
193
+ const userForm = new UserForm(usersDS);
194
+ const tasksDS = new DataSource({
195
+ data: [
196
+ { id: 1, title: 'Task 1', completed: false, priority: 'high', dueDate: new Date() },
197
+ { id: 2, title: 'Task 2', completed: true, priority: 'low', dueDate: new Date() }
198
+ ]
199
+ });
200
+ // Create computed values
201
+ const taskStats = {
202
+ total: createSignal(0),
203
+ completed: createSignal(0),
204
+ pending: createSignal(0),
205
+ highPriority: createSignal(0)
206
+ };
207
+ // Update stats when data changes
208
+ tasksDS.on('dataChanged', (tasks) => {
209
+ if (!tasks)
210
+ return;
211
+ taskStats.total.set(tasks.length);
212
+ taskStats.completed.set(tasks.filter(t => t.completed).length);
213
+ taskStats.pending.set(tasks.filter(t => !t.completed).length);
214
+ taskStats.highPriority.set(tasks.filter(t => t.priority === 'high').length);
215
+ });
216
+ // Subscribe to computed values
217
+ taskStats.pending.subscribe((count) => {
218
+ console.log(`Pending tasks: ${count}`);
219
+ });
220
+ // ============================================================================
221
+ // Example 10: Type Guards and Validation
222
+ // ============================================================================
223
+ function isValidUser(obj) {
224
+ return (typeof obj === 'object' &&
225
+ typeof obj.id === 'number' &&
226
+ typeof obj.name === 'string' &&
227
+ typeof obj.email === 'string' &&
228
+ typeof obj.age === 'number');
229
+ }
230
+ // Use type guard in middleware
231
+ usersDS.middleware.useBefore('create', async ({ record }) => {
232
+ if (!isValidUser(record)) {
233
+ throw new Error('Invalid user object');
234
+ }
235
+ // TypeScript now knows record is User
236
+ console.log(`Validating user: ${record.name}`);
237
+ });
238
+ // ============================================================================
239
+ // Export examples for use in other modules
240
+ // ============================================================================
241
+ export { usersDS, productsDS, tasksDS, crudExample, remoteExample, UserForm, isValidUser, taskStats };
242
+ //# sourceMappingURL=examples.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"examples.js","sourceRoot":"","sources":["../src/examples.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { DataSource } from './core/DataSource';
2
+ export { EventEmitter } from './core/EventEmitter';
3
+ export { MiddlewareManager } from './core/MiddlewareManager';
4
+ export { createSignal, reactive } from './core/Observable';
5
+ export { Container, container, dataSource, getDataSource } from './core/Container';
6
+ export { subscribe, unsubscribe, dispatch } from './core/Dispatcher';
7
+ export { Validator } from './core/validation';
8
+ export { BindraError, NetworkError, ValidationError, PermissionError, ConfigurationError, isBindraError, isNetworkError, isValidationError } from './core/errors';
9
+ export type { DataSourceConfig, Field, Permissions, QueryOptions, RetryConfig, CacheConfig, PaginationConfig, RealtimeConfig, SecurityConfig } from './core/DataSource';
10
+ export type { FieldConfig, FieldValidation } from './core/validation';
11
+ export type { Signal } from './core/Observable';
12
+ export { debounce, throttle, debounceWithMaxWait } from './utils/performance';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAGrE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAGvB,YAAY,EACV,gBAAgB,EAChB,KAAK,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,cAAc,EACf,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,WAAW,EACX,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ // Main entry point for Bindra library
2
+ export { DataSource } from './core/DataSource';
3
+ export { EventEmitter } from './core/EventEmitter';
4
+ export { MiddlewareManager } from './core/MiddlewareManager';
5
+ export { createSignal, reactive } from './core/Observable';
6
+ export { Container, container, dataSource, getDataSource } from './core/Container';
7
+ export { subscribe, unsubscribe, dispatch } from './core/Dispatcher';
8
+ // Export validation
9
+ export { Validator } from './core/validation';
10
+ // Export error classes
11
+ export { BindraError, NetworkError, ValidationError, PermissionError, ConfigurationError, isBindraError, isNetworkError, isValidationError } from './core/errors';
12
+ // Export performance utilities
13
+ export { debounce, throttle, debounceWithMaxWait } from './utils/performance';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAErE,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,uBAAuB;AACvB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAsBvB,+BAA+B;AAC/B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Creates a debounced version of a function that delays invoking until after
3
+ * a specified delay has elapsed since the last time it was invoked
4
+ *
5
+ * @param fn - The function to debounce
6
+ * @param delay - The delay in milliseconds
7
+ * @returns Debounced function
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const search = debounce((query: string) => {
12
+ * console.log('Searching for:', query);
13
+ * }, 300);
14
+ *
15
+ * search('a'); // Won't execute
16
+ * search('ab'); // Won't execute
17
+ * search('abc'); // Executes after 300ms
18
+ * ```
19
+ */
20
+ export declare function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void;
21
+ /**
22
+ * Creates a throttled version of a function that only invokes at most once
23
+ * per every specified milliseconds
24
+ *
25
+ * @param fn - The function to throttle
26
+ * @param limit - The minimum time between invocations in milliseconds
27
+ * @returns Throttled function
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * const handleScroll = throttle(() => {
32
+ * console.log('Scroll event');
33
+ * }, 100);
34
+ *
35
+ * window.addEventListener('scroll', handleScroll);
36
+ * ```
37
+ */
38
+ export declare function throttle<T extends (...args: any[]) => any>(fn: T, limit: number): (...args: Parameters<T>) => void;
39
+ /**
40
+ * Creates a function that delays invoking until after a specified delay,
41
+ * but also ensures it's called at least once every maxWait milliseconds
42
+ *
43
+ * @param fn - The function to debounce with max wait
44
+ * @param delay - The delay in milliseconds
45
+ * @param maxWait - Maximum time to wait before forcing invocation
46
+ * @returns Debounced function with max wait
47
+ */
48
+ export declare function debounceWithMaxWait<T extends (...args: any[]) => any>(fn: T, delay: number, maxWait: number): (...args: Parameters<T>) => void;
49
+ //# sourceMappingURL=performance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.d.ts","sourceRoot":"","sources":["../../src/utils/performance.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAOlC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,GACZ,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAUlC;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACnE,EAAE,EAAE,CAAC,EACL,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAkClC"}
@@ -0,0 +1,94 @@
1
+ // Performance utilities: debounce and throttle functions
2
+ /**
3
+ * Creates a debounced version of a function that delays invoking until after
4
+ * a specified delay has elapsed since the last time it was invoked
5
+ *
6
+ * @param fn - The function to debounce
7
+ * @param delay - The delay in milliseconds
8
+ * @returns Debounced function
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const search = debounce((query: string) => {
13
+ * console.log('Searching for:', query);
14
+ * }, 300);
15
+ *
16
+ * search('a'); // Won't execute
17
+ * search('ab'); // Won't execute
18
+ * search('abc'); // Executes after 300ms
19
+ * ```
20
+ */
21
+ export function debounce(fn, delay) {
22
+ let timeoutId;
23
+ return function (...args) {
24
+ clearTimeout(timeoutId);
25
+ timeoutId = setTimeout(() => fn.apply(this, args), delay);
26
+ };
27
+ }
28
+ /**
29
+ * Creates a throttled version of a function that only invokes at most once
30
+ * per every specified milliseconds
31
+ *
32
+ * @param fn - The function to throttle
33
+ * @param limit - The minimum time between invocations in milliseconds
34
+ * @returns Throttled function
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const handleScroll = throttle(() => {
39
+ * console.log('Scroll event');
40
+ * }, 100);
41
+ *
42
+ * window.addEventListener('scroll', handleScroll);
43
+ * ```
44
+ */
45
+ export function throttle(fn, limit) {
46
+ let inThrottle;
47
+ return function (...args) {
48
+ if (!inThrottle) {
49
+ fn.apply(this, args);
50
+ inThrottle = true;
51
+ setTimeout(() => (inThrottle = false), limit);
52
+ }
53
+ };
54
+ }
55
+ /**
56
+ * Creates a function that delays invoking until after a specified delay,
57
+ * but also ensures it's called at least once every maxWait milliseconds
58
+ *
59
+ * @param fn - The function to debounce with max wait
60
+ * @param delay - The delay in milliseconds
61
+ * @param maxWait - Maximum time to wait before forcing invocation
62
+ * @returns Debounced function with max wait
63
+ */
64
+ export function debounceWithMaxWait(fn, delay, maxWait) {
65
+ let timeoutId;
66
+ let maxWaitTimeoutId;
67
+ let lastArgs = null;
68
+ let lastThis = null;
69
+ const invokeFunc = () => {
70
+ if (lastArgs !== null && lastThis !== null) {
71
+ fn.apply(lastThis, lastArgs);
72
+ lastArgs = null;
73
+ lastThis = null;
74
+ }
75
+ };
76
+ return function (...args) {
77
+ lastArgs = args;
78
+ lastThis = this;
79
+ clearTimeout(timeoutId);
80
+ if (!maxWaitTimeoutId) {
81
+ maxWaitTimeoutId = setTimeout(() => {
82
+ invokeFunc();
83
+ clearTimeout(timeoutId);
84
+ maxWaitTimeoutId = undefined;
85
+ }, maxWait);
86
+ }
87
+ timeoutId = setTimeout(() => {
88
+ invokeFunc();
89
+ clearTimeout(maxWaitTimeoutId);
90
+ maxWaitTimeoutId = undefined;
91
+ }, delay);
92
+ };
93
+ }
94
+ //# sourceMappingURL=performance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.js","sourceRoot":"","sources":["../../src/utils/performance.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,QAAQ,CACtB,EAAK,EACL,KAAa;IAEb,IAAI,SAAwC,CAAC;IAE7C,OAAO,UAAqB,GAAG,IAAmB;QAChD,YAAY,CAAC,SAAS,CAAC,CAAC;QACxB,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;IAC5D,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,QAAQ,CACtB,EAAK,EACL,KAAa;IAEb,IAAI,UAAmB,CAAC;IAExB,OAAO,UAAqB,GAAG,IAAmB;QAChD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACrB,UAAU,GAAG,IAAI,CAAC;YAClB,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,UAAU,GAAG,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,EAAK,EACL,KAAa,EACb,OAAe;IAEf,IAAI,SAAwC,CAAC;IAC7C,IAAI,gBAA+C,CAAC;IACpD,IAAI,QAAQ,GAAyB,IAAI,CAAC;IAC1C,IAAI,QAAQ,GAAQ,IAAI,CAAC;IAEzB,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3C,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC7B,QAAQ,GAAG,IAAI,CAAC;YAChB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,UAAqB,GAAG,IAAmB;QAChD,QAAQ,GAAG,IAAI,CAAC;QAChB,QAAQ,GAAG,IAAI,CAAC;QAEhB,YAAY,CAAC,SAAS,CAAC,CAAC;QAExB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE;gBACjC,UAAU,EAAE,CAAC;gBACb,YAAY,CAAC,SAAS,CAAC,CAAC;gBACxB,gBAAgB,GAAG,SAAgB,CAAC;YACtC,CAAC,EAAE,OAAO,CAAC,CAAC;QACd,CAAC;QAED,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAC1B,UAAU,EAAE,CAAC;YACb,YAAY,CAAC,gBAAgB,CAAC,CAAC;YAC/B,gBAAgB,GAAG,SAAgB,CAAC;QACtC,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "bindra",
3
+ "version": "2.0.0",
4
+ "description": "Lightweight reactive data management library for TypeScript applications",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md",
18
+ "LICENSE",
19
+ "CHANGELOG.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "build:watch": "tsc --watch",
24
+ "dev": "tsc --watch",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest",
27
+ "test:ui": "vitest --ui",
28
+ "test:coverage": "vitest run --coverage",
29
+ "release": "npm version patch && npm publish",
30
+ "release:minor": "npm version minor && npm publish",
31
+ "release:major": "npm version major && npm publish"
32
+ },
33
+ "keywords": [
34
+ "reactive",
35
+ "data",
36
+ "datasource",
37
+ "mvvm",
38
+ "typescript",
39
+ "signals",
40
+ "crud",
41
+ "api",
42
+ "state-management",
43
+ "observable"
44
+ ],
45
+ "author": "Mohamad J. <mohamad-j@example.com>",
46
+ "license": "MIT",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/mohamad-j/Bindra.git",
50
+ "directory": "package"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/mohamad-j/Bindra/issues"
54
+ },
55
+ "homepage": "https://bindra-docs.web.app",
56
+ "packageManager": "pnpm@10.11.1",
57
+ "devDependencies": {
58
+ "@vitest/coverage-v8": "^4.0.16",
59
+ "@vitest/ui": "^4.0.16",
60
+ "happy-dom": "^20.0.11",
61
+ "typescript": "^5.3.3",
62
+ "vitest": "^4.0.16"
63
+ }
64
+ }