@buley/dash 0.0.30

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 (97) hide show
  1. package/.coveralls.yml +1 -0
  2. package/.github/workflows/opencommit.yml +33 -0
  3. package/.github/workflows/testing.yml +20 -0
  4. package/.gitmodules +0 -0
  5. package/README.md +98 -0
  6. package/behaviors/cache.dev.js +282 -0
  7. package/behaviors/changes.dev.js +337 -0
  8. package/behaviors/collect.dev.js +40 -0
  9. package/behaviors/examples/async.dev.js +17 -0
  10. package/behaviors/firebase.dev.js +283 -0
  11. package/behaviors/live.dev.js +67 -0
  12. package/behaviors/map.dev.js +54 -0
  13. package/behaviors/mapreduce.dev.js +68 -0
  14. package/behaviors/match.dev.js +66 -0
  15. package/behaviors/patch.dev.js +69 -0
  16. package/behaviors/rest.dev.js +340 -0
  17. package/behaviors/shorthand.dev.js +59 -0
  18. package/behaviors/stats.dev.js +672 -0
  19. package/dist/behaviors/index.js +142 -0
  20. package/dist/database/index.js +76 -0
  21. package/dist/databases/index.js +121 -0
  22. package/dist/entry/index.js +166 -0
  23. package/dist/index.js +93 -0
  24. package/dist/indexes/index.js +153 -0
  25. package/dist/store/index.js +97 -0
  26. package/dist/stores/index.js +90 -0
  27. package/dist/utilities/index.js +174 -0
  28. package/documentation/database/closing.md +3 -0
  29. package/documentation/database/getting.md +1 -0
  30. package/documentation/database/opening.md +5 -0
  31. package/documentation/database/removing.md +3 -0
  32. package/documentation/databases.md +21 -0
  33. package/documentation/entries.md +13 -0
  34. package/documentation/entry/adding.md +1 -0
  35. package/documentation/entry/getting.md +4 -0
  36. package/documentation/entry/putting.md +0 -0
  37. package/documentation/entry/removing.md +3 -0
  38. package/documentation/entry/updating.md +0 -0
  39. package/documentation/general/security.md +10 -0
  40. package/documentation/general/transaction/requests.md +3 -0
  41. package/documentation/general/transactions.md +5 -0
  42. package/documentation/index/creating.md +1 -0
  43. package/documentation/index/getting.md +1 -0
  44. package/documentation/index/iterating.md +1 -0
  45. package/documentation/index/removing.md +1 -0
  46. package/documentation/indexes.md +3 -0
  47. package/documentation/key/cursors.md +5 -0
  48. package/documentation/key/range/bounds.md +11 -0
  49. package/documentation/key/range/direction.md +1 -0
  50. package/documentation/key/ranges.md +3 -0
  51. package/documentation/keys.md +12 -0
  52. package/documentation/objectstore/clearing.md +1 -0
  53. package/documentation/objectstore/creating.md +1 -0
  54. package/documentation/objectstore/getting.md +1 -0
  55. package/documentation/objectstore/iteration.md +1 -0
  56. package/documentation/objectstore/removing.md +1 -0
  57. package/documentation/overview.md +5 -0
  58. package/documentation/stores.md +13 -0
  59. package/jest.config.js +12 -0
  60. package/package.json +40 -0
  61. package/src/behaviors/index.ts +140 -0
  62. package/src/database/index.ts +81 -0
  63. package/src/databases/index.ts +127 -0
  64. package/src/entry/index.ts +183 -0
  65. package/src/index/index.ts +61 -0
  66. package/src/index.ts +96 -0
  67. package/src/indexes/index.ts +151 -0
  68. package/src/store/index.ts +102 -0
  69. package/src/stores/index.ts +90 -0
  70. package/src/utilities/index.ts +349 -0
  71. package/tests/behaviors/behaviors.spec.ts +123 -0
  72. package/tests/database/database.spec.ts +177 -0
  73. package/tests/databases/databases.spec.ts +199 -0
  74. package/tests/entry/entry.spec.ts +252 -0
  75. package/tests/index/index.spec.ts +94 -0
  76. package/tests/indexes/indexes.spec.ts +203 -0
  77. package/tests/store/store.spec.ts +164 -0
  78. package/tests/stores/stores.spec.ts +148 -0
  79. package/tests/utilities/clone.spec.ts +48 -0
  80. package/tests/utilities/cloneError.spec.ts +33 -0
  81. package/tests/utilities/contains.spec.ts +28 -0
  82. package/tests/utilities/exists.spec.ts +21 -0
  83. package/tests/utilities/is.spec.ts +37 -0
  84. package/tests/utilities/isArray.spec.ts +21 -0
  85. package/tests/utilities/isBoolean.spec.ts +23 -0
  86. package/tests/utilities/isEmpty.spec.ts +45 -0
  87. package/tests/utilities/isFunction.spec.ts +30 -0
  88. package/tests/utilities/isNumber.spec.ts +29 -0
  89. package/tests/utilities/isObject.spec.ts +42 -0
  90. package/tests/utilities/isRegEx.spec.ts +33 -0
  91. package/tests/utilities/isString.spec.ts +25 -0
  92. package/tests/utilities/isnt.spec.ts +50 -0
  93. package/tests/utilities/randomId.spec.ts +39 -0
  94. package/tests/utilities/safeApply.spec.ts +49 -0
  95. package/tests/utilities/safeEach.spec.ts +38 -0
  96. package/tests/utilities/safeIterate.spec.ts +47 -0
  97. package/tsconfig.json +16 -0
package/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ repo_token: lEBGXHtQZ1qbYV4G5MRkyqwDEZmWStEg8
@@ -0,0 +1,33 @@
1
+ # https://github.com/di-sukharev/opencommit
2
+ name: 'Commit Reshaping'
3
+
4
+ on:
5
+ push:
6
+ branches-ignore: [main dev development release]
7
+
8
+ jobs:
9
+ opencommit:
10
+ timeout-minutes: 5
11
+ name: Commit Reshaping (OpenCommit)
12
+ runs-on: ubuntu-latest
13
+ permissions: write-all
14
+ steps:
15
+ - name: Setup Node.js Environment
16
+ uses: actions/setup-node@v2
17
+ with:
18
+ node-version: '16'
19
+ - uses: actions/checkout@v3
20
+ with:
21
+ fetch-depth: 0
22
+ - uses: di-sukharev/opencommit@github-action-v1.0.4
23
+ with:
24
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25
+ env:
26
+ OCO_OPENAI_MAX_TOKENS: 500
27
+ OCO_OPENAI_API_KEY: ${{ secrets.OCO_OPENAI_API_KEY }}
28
+ OCO_OPENAI_BASE_PATH: ''
29
+ OCO_DESCRIPTION: false
30
+ OCO_EMOJI: true
31
+ OCO_MODEL: gpt-4
32
+ OCO_LANGUAGE: en
33
+ OCO_MESSAGE_TEMPLATE_PLACEHOLDER: '$msg'
@@ -0,0 +1,20 @@
1
+ name: Unit Testing
2
+
3
+ on: [pull_request]
4
+
5
+ jobs:
6
+ unit-test:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ node-version: [20.x]
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+ - name: Use Node.js ${{ matrix.node-version }}
14
+ uses: actions/setup-node@v2
15
+ with:
16
+ node-version: ${{ matrix.node-version }}
17
+ - name: Install dependencies
18
+ run: npm install
19
+ - name: Run Unit Tests
20
+ run: npm run test:unit
package/.gitmodules ADDED
File without changes
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Dash
2
+
3
+ Dash is a simple, lightweight wrapper around the IndexedDB API. It provides a promise-based interface for working with IndexedDB, making it easier to perform database operations in web applications.
4
+
5
+ ## Features
6
+
7
+ - Promise-based API for IndexedDB operations
8
+ - Modular design with separate modules for databases, stores, indexes, and entries
9
+ - Built-in error handling and type safety with TypeScript
10
+ - Support for custom behaviors and extensions
11
+ - Lightweight and easy to integrate into existing projects
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @buley/dash
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ Here's a basic example of how to use Dash:
22
+
23
+ ```javascript
24
+ import dash from '@buley/dash';
25
+
26
+ // Open a database
27
+ dash.database.open({ database: 'myDB', version: 1 })
28
+ .then(ctx => {
29
+ // Create an object store
30
+ return dash.stores.add({
31
+ ...ctx,
32
+ store: 'myStore',
33
+ store_key_path: 'id',
34
+ auto_increment: true
35
+ });
36
+ })
37
+ .then(ctx => {
38
+ // Add an entry to the store
39
+ return dash.entry.add({
40
+ ...ctx,
41
+ data: { name: 'John Doe', age: 30 }
42
+ });
43
+ })
44
+ .then(ctx => {
45
+ console.log('Entry added successfully:', ctx.entry);
46
+ })
47
+ .catch(error => {
48
+ console.error('An error occurred:', error);
49
+ });
50
+ ```
51
+
52
+ ## API Reference
53
+
54
+ Dash provides methods for working with databases, stores, indexes, and entries. Here are some of the key modules:
55
+
56
+ - `dash.database`: Methods for working with databases (open, close, delete)
57
+ - `dash.stores`: Methods for working with object stores (add, remove, get)
58
+ - `dash.indexes`: Methods for working with indexes (add, remove, get)
59
+ - `dash.entry`: Methods for working with individual entries (add, get, put, remove, update, count)
60
+
61
+ Each module provides methods that return promises, allowing for easy chaining of operations.
62
+
63
+ ## Behaviors
64
+
65
+ Dash supports custom behaviors that can be added to modify or extend its functionality. Behaviors can be used to implement logging, validation, or any custom logic you need.
66
+
67
+ ```javascript
68
+ dash.behaviors.add((ctx) => {
69
+ console.log('Operation:', ctx.type, ctx.method);
70
+ return ctx;
71
+ });
72
+ ```
73
+
74
+ ### Testing
75
+
76
+ To run unit tests:
77
+
78
+ ```
79
+ npm run test
80
+ ```
81
+
82
+ [![Coverage Status](https://coveralls.io/repos/github/buley/dash/badge.svg?branch=master)](https://coveralls.io/github/buley/dash?branch=master)
83
+
84
+ ## Contributing
85
+
86
+ Contributions are welcome! Please feel free to submit a Pull Request.
87
+
88
+ ## License
89
+
90
+ This project is licensed under the MIT License.
91
+
92
+ ## Author
93
+
94
+ [Taylor Buley](https://buley.info) (@taylorbuley)
95
+
96
+ ---
97
+
98
+ Version: 0.0.30
@@ -0,0 +1,282 @@
1
+ var dashCache = (function (environment) {
2
+ "use strict";
3
+ var that,
4
+ cache = {},
5
+ set = function( request ) {
6
+ var key = request.key || null
7
+ , value = request.value || null
8
+ , expires = request.expires || 3000 //in millisecons
9
+ , current_date = new Date()
10
+ , timestamp = ( current_date.getTime() + expires );
11
+ if( 'undefined' === typeof key || null === key ) {
12
+ return;
13
+ }
14
+ cache = cache || {};
15
+ cache[ key ] = {
16
+ data: value,
17
+ expire: timestamp
18
+ };
19
+ return cache[ key ].data;
20
+ },
21
+ get = function( request ) {
22
+ cache = cache || {};
23
+ var key = request.key || '';
24
+ if( 'undefined' === typeof key || null === key ) {
25
+ return null;
26
+ }
27
+ if(cache[ key ]) {
28
+ if(cache[ key ].expire > new Date().getTime()) {
29
+ cache[ key ].data = cache[ key ].data || {};
30
+ return cache[ key ].data;
31
+ }
32
+ delete cache[key];
33
+ }
34
+ return null;
35
+ },
36
+ zap = function( request ) {
37
+ cache = cache || {};
38
+ var key = request.key || ''
39
+ , temp
40
+ , keys = key.split('.')
41
+ , result;
42
+ if( 'undefined' === typeof key || null === key ) {
43
+ return;
44
+ }
45
+ result = cache[ key ];
46
+ delete cache[ key ];
47
+ return result;
48
+ },
49
+ buildKey = function(key_ctx, type) {
50
+ var key = [ key_ctx.database, key_ctx.store, key_ctx.index, key_ctx.key, key_ctx.primary_key, key_ctx.limit ].reduce(function(acc, current){
51
+ acc = acc || [];
52
+ if(!!current) {
53
+ acc = [ acc, current ].join('.');
54
+ }
55
+ return acc;
56
+ });
57
+ return key;
58
+ },
59
+ scripts = ( !! environment.document) ? environment.document.getElementsByTagName("script") : [],
60
+ libraryScript = scripts[scripts.length - 1] || null,
61
+ libraryPath =( null !== libraryScript && null !== libraryScript.src.match(/cache/) && null === libraryScript.src.match(/chrome-extension/) ) ? libraryScript.src : self.currentScript || null,
62
+ workerEnvironment = null !== environment.constructor.toString().match(/WorkerGlobalScope/),
63
+ worker = !!workerEnvironment && !!libraryPath && null !== libraryPath.match(/cache/) && undefined !== Worker ? new Worker(libraryPath) : null,
64
+ workQueue = {},
65
+ workRegister = function (worker, message, context, success, error, notify) {
66
+ var id = that.random(),
67
+ callback = function (e) {
68
+ var data = e.data,
69
+ queued = workQueue[data.uid];
70
+ if (undefined !== queued) {
71
+ switch (e.data.type) {
72
+ case 'success':
73
+ delete workQueue[data.uid];
74
+ worker.removeEventListener('message', callback);
75
+ that.apply(success, [data.context]);
76
+ break;
77
+ case 'error':
78
+ delete workQueue[data.uid];
79
+ worker.removeEventListener('message', callback);
80
+ that.apply(error, [data.context]);
81
+ break;
82
+ case 'abort':
83
+ that.apply(notify, [data.context]);
84
+ break;
85
+ default:
86
+ break;
87
+ }
88
+ }
89
+ },
90
+ clean = function(obj) {
91
+ if (that.isFunction(obj)) {
92
+ return undefined;
93
+ } else if (that.isObject(obj)) {
94
+ that.iterate(obj, function(key, val) {
95
+ obj[ key ] = clean(val);
96
+ });
97
+ } else if (that.isArray(obj)) {
98
+ that.each(obj, function(v, i) {
99
+ obj[i] = clean(v);
100
+ });
101
+ }
102
+ return obj;
103
+ };
104
+ workQueue[id] = {
105
+ success: success,
106
+ error: error,
107
+ notify: notify
108
+ };
109
+ if ( !!worker ) {
110
+ worker.addEventListener('message', callback);
111
+ worker.postMessage({
112
+ method: message,
113
+ context: clean(context),
114
+ uid: id
115
+ });
116
+ } else {
117
+ throw new Error('non-Worker interface not yet implemented');
118
+ }
119
+ return id;
120
+ },
121
+ workDispatch = function (message, context) {
122
+ var defd = that.deferred(),
123
+ callbacks = {
124
+ on_success: context.on_success,
125
+ on_error: context.on_error,
126
+ on_abort: context.on_abort,
127
+ on_complete: context.on_complete,
128
+ on_upgrade_needed: context.on_upgrade_needed,
129
+ on_blocked: context.on_blocked,
130
+ on_close: context.on_close
131
+ },
132
+ getData = function (data) {
133
+ if( that.isObject(data) ) {
134
+ that.iterate(callbacks, function (key, val) {
135
+ data[key] = val;
136
+ });
137
+ }
138
+ return data;
139
+ };
140
+ that.iterate(callbacks, function (key, val) {
141
+ delete context[key];
142
+ });
143
+ workRegister(worker, message, context, function (data) {
144
+ defd.resolve(getData(data));
145
+ }, function (data) {
146
+ defd.reject(getData(data));
147
+ }, function (data) {
148
+ defd.notify(getData(data));
149
+ });
150
+ return defd.promise;
151
+ };
152
+
153
+ if (true === workerEnvironment) {
154
+ environment.addEventListener('message', function (e) {
155
+ var input = e.data,
156
+ method = input.method,
157
+ value = input.value,
158
+ key = input.key,
159
+ context = input.context,
160
+ expires = input.expires,
161
+ prune = function(obj) {
162
+ var isReducible = function(input) {
163
+ var attrs = 0,
164
+ attr;
165
+ if ( undefined === input || null === input || 'string' === typeof input || 'number' === typeof input || 'function' === typeof input.slice ) {
166
+ return false;
167
+ }
168
+ for ( attr in input ) {
169
+ if ( true === input.hasOwnProperty(attr) ) {
170
+ attrs += 1;
171
+ }
172
+ }
173
+ return ( attrs >= 1 ) ? true : false;
174
+ }, reduce = function(input) {
175
+ var attrs = {},
176
+ attr;
177
+ for ( attr in input ) {
178
+ if ( true === input.hasOwnProperty(attr) ) {
179
+ if ( !!input[ attr ] && !!input[ attr ].expire && ( input[ attr ].expire < new Date().getTime() ) ) {
180
+ //skip
181
+ } else if ( isReducible(input[ attr ] ) ) {
182
+ attrs[ attr ] = reduce(input[ attr ]);
183
+ } else {
184
+ attrs[ attr ] = input[ attr ];
185
+ }
186
+ }
187
+ }
188
+ return attrs
189
+ };
190
+ return reduce(obj);
191
+ },
192
+ end = function (ctx) {
193
+ input.context = ctx;
194
+ input.type = 'success';
195
+ environment.postMessage(input);
196
+ setTimeout(function() {
197
+ cache = prune(cache);
198
+ });
199
+ };
200
+ if (method === 'get' || method === 'set' || method === 'delete') {
201
+ if ( method === 'get' ) {
202
+ end(get(context));
203
+ } else if ( method === 'set' ) {
204
+ end(set(context));
205
+ } else if ( method === 'delete' ) {
206
+ end(zap(context));
207
+ }
208
+ } else {
209
+ input.type = 'error';
210
+ end({
211
+ type: 'abort',
212
+ context: input,
213
+ error: 'No such method'
214
+ });
215
+ }
216
+ }, false);
217
+ } else {
218
+ return [ function (state) {
219
+ that = this;
220
+ if(this.isEmpty(state.context.cache)) {
221
+ return state;
222
+ }
223
+ var promise = state.promise,
224
+ outward = this.deferred(),
225
+ inward,
226
+ response,
227
+ callbacks = {
228
+ on_success: state.context.on_success,
229
+ on_error: state.context.on_error,
230
+ on_abort: state.context.on_abort,
231
+ on_complete: state.context.on_complete,
232
+ on_upgrade_needed: state.context.on_upgrade_needed,
233
+ on_blocked: state.context.on_blocked,
234
+ on_close: state.context.on_close
235
+ }
236
+ if (this.contains(['get.entry'], state.method)) {
237
+ inward = workDispatch('get', { key: buildKey(state.context) } );
238
+ inward(function(response) {
239
+ if(that.isEmpty(response)) {
240
+ state.context.cached = false;
241
+ } else {
242
+ state = response;
243
+ state.promise = outward.promise;
244
+ state.context.cached = true;
245
+ that.iterate(callbacks, function(key, val) {
246
+ if (!that.isEmpty(val)) {
247
+ state.context[key] = val;
248
+ }
249
+ });
250
+ state.type = 'resolve';
251
+ outward.resolve(state);
252
+ }
253
+ });
254
+ }
255
+ return state;
256
+ }, function (state) {
257
+ if(this.is(state.context.cached, true) || this.is(state.context.cache, false)) {
258
+ return state;
259
+ }
260
+ var promise = state.promise,
261
+ outward = this.deferred(),
262
+ inward,
263
+ response,
264
+ args;
265
+ if (this.contains(['resolve','error'], state.type)) {
266
+ state.promise = outward.promise;
267
+ args = { key: buildKey(state.context, state.type) } ;
268
+ if ( !this.isEmpty(state.context.purge) || this.contains(['remove.entry', 'remove.entries', 'remove.index', 'remove.store', 'remove.database' ], state.method) ) {
269
+ inward = workDispatch('zap', args );
270
+ } else {
271
+ args.expires = state.context.expires || 3000;
272
+ args.value = state;
273
+ inward = workDispatch('set', args );
274
+ }
275
+ inward(function(ctx2){
276
+ outward.resolve(ctx2);
277
+ });
278
+ }
279
+ return state;
280
+ } ];
281
+ }
282
+ }(self));