@live-change/dao 0.4.9 → 0.4.13
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/browser.js +4 -0
- package/index.js +3 -0
- package/lib/InboxReader.js +97 -0
- package/lib/ObservableList.js +1 -1
- package/lib/Path.js +4 -3
- package/package.json +2 -2
- package/tests/path.js +3 -2
package/browser.js
CHANGED
|
@@ -34,6 +34,10 @@ import DaoCache from "./lib/DaoCache.js"
|
|
|
34
34
|
rd.DaoCache = DaoCache
|
|
35
35
|
export { DaoCache }
|
|
36
36
|
|
|
37
|
+
import InboxReader from "./lib/InboxReader.js"
|
|
38
|
+
rd.InboxReader = InboxReader
|
|
39
|
+
export { InboxReader }
|
|
40
|
+
|
|
37
41
|
import ReactiveConnection from "./lib/ReactiveConnection.js"
|
|
38
42
|
rd.ReactiveConnection = ReactiveConnection
|
|
39
43
|
export { ReactiveConnection }
|
package/index.js
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
|
|
2
|
+
class InboxReader {
|
|
3
|
+
constructor(observableFunction, callback, start = '', bucketSize = 32) {
|
|
4
|
+
this.observableFunction = observableFunction
|
|
5
|
+
this.position = start
|
|
6
|
+
this.callback = callback
|
|
7
|
+
this.bucketSize = bucketSize
|
|
8
|
+
|
|
9
|
+
this.observable = null
|
|
10
|
+
this.queue = []
|
|
11
|
+
this.processingPromise = null
|
|
12
|
+
this.finished = false
|
|
13
|
+
this.readPromise = null
|
|
14
|
+
this.readPromiseResolve = null
|
|
15
|
+
|
|
16
|
+
this.observer = (signal, ...args) => {
|
|
17
|
+
if(signal == 'error') {
|
|
18
|
+
const error = args[0]
|
|
19
|
+
console.error("PEER MESSAGE ERROR", error.stack || error)
|
|
20
|
+
return
|
|
21
|
+
}
|
|
22
|
+
if(signal == 'putByField') {
|
|
23
|
+
const [field, id, message] = args
|
|
24
|
+
this.handleMessage(message)
|
|
25
|
+
} else if(signal == 'set') {
|
|
26
|
+
const value = args[0]
|
|
27
|
+
for (const message of value) {
|
|
28
|
+
this.handleMessage(message)
|
|
29
|
+
}
|
|
30
|
+
} else if(signal == 'push') {
|
|
31
|
+
const [message] = args
|
|
32
|
+
this.handleMessage(message)
|
|
33
|
+
} else {
|
|
34
|
+
console.error("INBOX READER SIGNAL NOT HANDLED", signal)
|
|
35
|
+
}
|
|
36
|
+
this.startProcessing()
|
|
37
|
+
this.observeNext()
|
|
38
|
+
}
|
|
39
|
+
this.observeNext()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
observeNext() {
|
|
43
|
+
if(this.queue.length > this.bucketSize) return // no need to observe, there is work to do
|
|
44
|
+
if(this.observable) {
|
|
45
|
+
const observableValue = this.observable.getValue()
|
|
46
|
+
if(!observableValue) return // still loading data
|
|
47
|
+
if(observableValue.length < this.bucketSize) return // we are waiting for more
|
|
48
|
+
}
|
|
49
|
+
if(this.observable) {
|
|
50
|
+
this.observable.unobserve(this.observer)
|
|
51
|
+
this.observable = null
|
|
52
|
+
}
|
|
53
|
+
this.readPromise = new Promise(resolve => this.readPromiseResolve = resolve)
|
|
54
|
+
this.observable = this.observableFunction(this.position, this.bucketSize)
|
|
55
|
+
this.observable.observe(this.observer)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
handleMessage(message) {
|
|
59
|
+
if(message.id <= this.position) return // ignore
|
|
60
|
+
this.position = message.id
|
|
61
|
+
this.queue.push(message)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
startProcessing() {
|
|
65
|
+
if(!this.processingPromise) {
|
|
66
|
+
this.processingPromise = this.doProcessing()
|
|
67
|
+
this.processingPromise.then(() => this.processingPromise = null)
|
|
68
|
+
}
|
|
69
|
+
return this.processingPromise
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async doProcessing() {
|
|
73
|
+
while(this.queue.length > 0 && !this.finished) {
|
|
74
|
+
const message = this.queue.shift()
|
|
75
|
+
await this.callback(message)
|
|
76
|
+
this.observeNext() // observe if needed
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async sync() {
|
|
81
|
+
while(this.queue.length > 0 || this.readPromise) {
|
|
82
|
+
if(this.queue.length > 0) await this.startProcessing()
|
|
83
|
+
if(this.readPromise) await this.readPromise
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
dispose() {
|
|
88
|
+
this.finished = true
|
|
89
|
+
if(this.observable) {
|
|
90
|
+
this.observable.unobserve(this.observer)
|
|
91
|
+
this.observable = null
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = InboxReader
|
package/lib/ObservableList.js
CHANGED
|
@@ -65,7 +65,7 @@ class ObservableList extends Observable {
|
|
|
65
65
|
if(i == l) this.list.push(element)
|
|
66
66
|
} else {
|
|
67
67
|
let i
|
|
68
|
-
for(i = this.list.length-1; i >= 0; i--) {
|
|
68
|
+
for(i = this.list.length - 1; i >= 0; i--) {
|
|
69
69
|
if(this.list[i][field] == value) {
|
|
70
70
|
oldElement = this.list[i]
|
|
71
71
|
this.list.splice(i, 1, element)
|
package/lib/Path.js
CHANGED
|
@@ -71,16 +71,17 @@ class Path {
|
|
|
71
71
|
}
|
|
72
72
|
return new Path(this.what, newMore, this.to, this.actions)
|
|
73
73
|
}
|
|
74
|
-
action(paramsFunc) {
|
|
74
|
+
action(name, paramsFunc) {
|
|
75
75
|
let newActions = this.actions ? this.actions.slice() : []
|
|
76
76
|
const source = sourceProxy()
|
|
77
|
-
const actionObject = paramsFunc(source)
|
|
77
|
+
const actionObject = (paramsFunc || to)(source)
|
|
78
78
|
const path = actionObject.slice(0, -1)
|
|
79
79
|
const params = actionObject[actionObject.length - 1]
|
|
80
80
|
let processedParams = processParams(params)
|
|
81
81
|
const action = {
|
|
82
|
+
name: paramsFunc ? name : undefined,
|
|
82
83
|
path,
|
|
83
|
-
params: { object: processedParams }
|
|
84
|
+
params: { object: processedParams },
|
|
84
85
|
}
|
|
85
86
|
newActions.push(action)
|
|
86
87
|
return new Path(this.what, this.more, this.to, newActions)
|
package/package.json
CHANGED
package/tests/path.js
CHANGED
|
@@ -49,9 +49,10 @@ test("Path", t => {
|
|
|
49
49
|
|
|
50
50
|
t.test("tasks with delete actions", t => {
|
|
51
51
|
t.plan(1)
|
|
52
|
-
const path = tasks({ }).action(task => deleteTask({ task: task.id }))
|
|
52
|
+
const path = tasks({ }).action('delete', task => deleteTask({ task: task.id }))
|
|
53
|
+
console.log(JSON.stringify(path))
|
|
53
54
|
t.deepEqual(clean(path), {"what":["tasks",{}],"actions":[
|
|
54
|
-
{"path":["tasks"],"params":{"object":{"task":{"property":"id"}}}}
|
|
55
|
+
{"name":"delete","path":["tasks"],"params":{"object":{"task":{"property":"id"}}}}
|
|
55
56
|
]})
|
|
56
57
|
})
|
|
57
58
|
|