@live-change/framework 0.9.87 → 0.9.88

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.
package/lib/App.js CHANGED
@@ -631,6 +631,29 @@ class App {
631
631
  return await view.get(params, { internal: true, roles: ['admin'] })
632
632
  }
633
633
 
634
+ async cachedTask(taskDescription, expireAfter, task) {
635
+ const taskDescriptionHash = crypto.createHash('sha256').update(taskDescription).digest('hex')
636
+ let cacheEntry = await this.dao.get(['database', 'tableObject', this.databaseName, 'cache', taskDescriptionHash])
637
+ if(!cacheEntry || cacheEntry.createdAt < new Date(Date.now() - expireAfter).toISOString()) {
638
+ const result = await task()
639
+ const expiresAt = new Date(Date.now() + expireAfter).toISOString()
640
+ cacheEntry = {
641
+ id: taskDescriptionHash,
642
+ createdAt: new Date().toISOString(),
643
+ expiresAt: expiresAt > cacheEntry.expiresAt ? expiresAt : cacheEntry.expiresAt,
644
+ result
645
+ }
646
+ await this.dao.request(['database', 'put'], this.databaseName, 'cache', cacheEntry)
647
+ } else { // extend cache entry expiration
648
+ const newExpiresAt = new Date(new Date(cacheEntry.createdAt).getTime() + expireAfter).toISOString()
649
+ if(cacheEntry.expiresAt < newExpiresAt) {
650
+ cacheEntry.expiresAt = newExpiresAt
651
+ await this.dao.request(['database', 'put'], this.databaseName, 'cache', cacheEntry)
652
+ }
653
+ }
654
+ return cacheEntry.result
655
+ }
656
+
634
657
  }
635
658
 
636
659
  export default App
@@ -11,15 +11,17 @@ import { crudChanges, definitionToJSON } from "../utils.js"
11
11
 
12
12
  function createModelProxy(definition, model) {
13
13
  return new Proxy(model, {
14
- get(target, prop, receiver) {
15
- const runtime = definition._runtime
14
+ get(target, prop, receiver) {
15
+ const runtime = definition._runtime
16
16
  if(runtime) {
17
17
  const modelRuntime = runtime.models[model.name]
18
18
  if(modelRuntime[prop]) {
19
19
  return Reflect.get(modelRuntime, prop, receiver)
20
20
  }
21
21
  }
22
- return Reflect.get(target, prop, receiver)
22
+ const resutlt = Reflect.get(target, prop, receiver)
23
+ if(!resutlt) console.warn("Model runtime used before created", model.name)
24
+ return resutlt
23
25
  }
24
26
  })
25
27
  }
@@ -10,6 +10,17 @@ async function update(changes, service, app, force) {
10
10
  const dao = app.dao
11
11
  const database = app.databaseName
12
12
 
13
+ if(!app.noCache) {
14
+ dao.request(['database', 'createTable'], database, 'cache').catch(e => 'ok')
15
+ dao.request(['database', 'createIndex'], database, 'cache_byTimestamp', `${
16
+ async (input, output) => {
17
+ await input.table('cache').onChange((obj, oldObj) => {
18
+ if(obj && !oldObj) output.change({ id: obj.expiresAt+'_'+obj.id, to: obj.id }, null)
19
+ })
20
+ }
21
+ }`, {}).catch(e => 'ok')
22
+ }
23
+
13
24
  if(!app.shortEvents) {
14
25
  dao.request(['database', 'createTable'], database, 'eventConsumers').catch(e => 'ok')
15
26
  dao.request(['database', 'createTable'], database, 'eventReports').catch(e => 'ok')
@@ -60,6 +71,28 @@ async function update(changes, service, app, force) {
60
71
  requestTimeout: 10 * 60 * 1000 // 10 minutes?
61
72
  }
62
73
 
74
+ async function doCreateIndexIfNotExists(indexName, functionCode, parameters, storage) {
75
+ try {
76
+ await dao.requestWithSettings(indexRequestSettings, ['database', 'createIndex'], database, indexName,
77
+ functionCode, parameters, storage)
78
+ } catch(e) {
79
+ if(e.message.includes("already exists")) {
80
+ const indexConfig = await dao.get(['database', 'indexConfig', database, indexName])
81
+ const requiredConfig = {
82
+ name: indexName,
83
+ functionCode,
84
+ parameters,
85
+ storage
86
+ }
87
+ const match = JSON.stringify(indexConfig) === JSON.stringify(requiredConfig)
88
+ if(!match) {
89
+ console('ERROR INDEX MATCH', indexConfig, requiredConfig, "MATCH", match)
90
+ }
91
+ }
92
+ throw e
93
+ }
94
+ }
95
+
63
96
  async function createIndex(table, indexName, index) {
64
97
  if(table) {
65
98
  indexName = table + '_' + indexName
@@ -120,8 +153,7 @@ async function update(changes, service, app, force) {
120
153
  }
121
154
  const functionCode = `(${func})`
122
155
  ;(globalThis.compiledFunctionsCandidates = globalThis.compiledFunctionsCandidates || {})[functionCode] = func
123
- await dao.requestWithSettings(indexRequestSettings, ['database', 'createIndex'], database, indexName,
124
- functionCode, { properties, table, hash: index.hash }, index.storage ?? {})
156
+ await doCreateIndexIfNotExists(indexName, functionCode, { properties, table, hash: index.hash }, index.storage ?? {})
125
157
  } else {
126
158
  if(!table) throw new Error("only function indexes are possible without table")
127
159
  const properties = (Array.isArray(index.property) ? index.property : [index.property]).map(p => p.split('.'))
@@ -139,8 +171,7 @@ async function update(changes, service, app, force) {
139
171
  }
140
172
  const functionCode = `(${func})`
141
173
  ;(globalThis.compiledFunctionsCandidates = globalThis.compiledFunctionsCandidates || {})[functionCode] = func
142
- await dao.requestWithSettings(indexRequestSettings, ['database', 'createIndex'], database, indexName,
143
- functionCode, { properties, table, hash: index.hash }, index.storage ?? {})
174
+ await doCreateIndexIfNotExists(indexName, functionCode, { properties, table, hash: index.hash }, index.storage ?? {})
144
175
  }
145
176
  }
146
177
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/framework",
3
- "version": "0.9.87",
3
+ "version": "0.9.88",
4
4
  "description": "Live Change Framework - ultimate solution for real time mobile/web apps",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "homepage": "https://github.com/live-change/live-change-stack",
24
24
  "devDependencies": {
25
- "@live-change/dao": "^0.9.87",
26
- "@live-change/uid": "^0.9.87",
25
+ "@live-change/dao": "^0.9.88",
26
+ "@live-change/uid": "^0.9.88",
27
27
  "typedoc": "0.28.3",
28
28
  "typedoc-plugin-markdown": "^4.6.3",
29
29
  "typedoc-plugin-rename-defaults": "^0.7.3"
30
30
  },
31
- "gitHead": "7a7694ad2801b7ffa16f347aed441ca5f81ab5fd"
31
+ "gitHead": "c042d36f63a6cc50158c3b3385f7f21ea98b847d"
32
32
  }