entangld 2.6.0 → 2.7.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.
- package/.github/workflows/mocha-tests.yml +1 -1
- package/API.md +754 -0
- package/README.md +212 -799
- package/docs/protocol.md +484 -0
- package/generate_docs.js +3 -3
- package/lib/Datastore.js +142 -19
- package/lib/Message.js +9 -10
- package/lib/Subscription.js +23 -0
- package/lib/error.js +15 -0
- package/package.json +1 -1
- package/test/signals.js +590 -0
- package/test/sockets.js +7 -2
- package/test/tests.js +10 -0
- package/test/timeouts.js +173 -0
- package/.gitmodules +0 -3
- package/README.hbs +0 -190
- package/tags +0 -244
package/API.md
ADDED
|
@@ -0,0 +1,754 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
## Classes
|
|
4
|
+
|
|
5
|
+
<dl>
|
|
6
|
+
<dt><a href="#Entangld">Entangld</a> ⇐ <code>EventEmitter</code></dt>
|
|
7
|
+
<dd><p>Synchronized Event Store</p>
|
|
8
|
+
</dd>
|
|
9
|
+
<dt><a href="#EntangldError">EntangldError</a></dt>
|
|
10
|
+
<dd><p>Error class for Entangld.</p>
|
|
11
|
+
</dd>
|
|
12
|
+
<dt><a href="#EntangldTimeoutError">EntangldTimeoutError</a> ⇐ <code><a href="#EntangldError">EntangldError</a></code></dt>
|
|
13
|
+
<dd><p>Error for a request which got no reply in time.</p>
|
|
14
|
+
</dd>
|
|
15
|
+
<dt><a href="#RPCError">RPCError</a></dt>
|
|
16
|
+
<dd><p>Remote Error class for Entangld.</p>
|
|
17
|
+
</dd>
|
|
18
|
+
<dt><a href="#Entangld_Message">Entangld_Message</a></dt>
|
|
19
|
+
<dd><p>Message class for Entangld.</p>
|
|
20
|
+
<p>These messages are used for executing datastore operations between
|
|
21
|
+
remote datastores. In these relationships, there is always an upstream
|
|
22
|
+
and downstream pair, so that <code>get</code>, <code>set</code>, <code>push</code>, <code>subscribe</code> and <code>unsubscribe</code>
|
|
23
|
+
messages are created upstream and passed downstream while <code>event</code> and <code>value</code>
|
|
24
|
+
messages are created downstream and are passed back up. To maintain consistency,
|
|
25
|
+
the internal <code>.path</code> attribute
|
|
26
|
+
will always refer a path relative to the downstream datastore, since the
|
|
27
|
+
downstream datastores do not necessarilly have access to the upstream store
|
|
28
|
+
structure, and so cannot generally construct upstream paths. This means that
|
|
29
|
+
the <code>.path</code> attribute is a <code>tree</code> relative to the upstream datastore, and
|
|
30
|
+
the upstream path can be reconstructed as:</p>
|
|
31
|
+
<pre><code class="language-js">upstream._namespaces.get(downstream) + "." + msg.path;
|
|
32
|
+
</code></pre>
|
|
33
|
+
<p>Since <code>unsubscribe</code> messages identify a subscription by its <code>.uuid</code>, they should
|
|
34
|
+
have their <code>.path</code> attributes set to undefined or null.</p>
|
|
35
|
+
<p>Most messages will also have a <code>.uuid</code> attribute. For <code>get</code>/<code>value</code> messages,
|
|
36
|
+
this allows for the value to be properly linked back up with the original <code>get</code>
|
|
37
|
+
message. For the <code>subscribe</code>/<code>unsubscribe</code>/<code>event</code> messages, this allows for
|
|
38
|
+
callback functions to be trigger properly, and for unsubscribe messages to
|
|
39
|
+
propogate down the chain. <code>set</code>/<code>push</code> messages do not use the <code>.uuid</code> attribute
|
|
40
|
+
since they require no response.</p>
|
|
41
|
+
</dd>
|
|
42
|
+
<dt><a href="#Subscription">Subscription</a></dt>
|
|
43
|
+
<dd><p>A datastore subscription object</p>
|
|
44
|
+
</dd>
|
|
45
|
+
</dl>
|
|
46
|
+
|
|
47
|
+
<a name="Entangld"></a>
|
|
48
|
+
|
|
49
|
+
## Entangld ⇐ <code>EventEmitter</code>
|
|
50
|
+
Synchronized Event Store
|
|
51
|
+
|
|
52
|
+
**Kind**: global class
|
|
53
|
+
**Extends**: <code>EventEmitter</code>
|
|
54
|
+
|
|
55
|
+
* [Entangld](#Entangld) ⇐ <code>EventEmitter</code>
|
|
56
|
+
* [.namespaces](#Entangld+namespaces) ⇒ <code>array</code>
|
|
57
|
+
* [.subscriptions](#Entangld+subscriptions) ⇒ [<code>Array.<Subscription></code>](#Subscription)
|
|
58
|
+
* [.namespace()](#Entangld+namespace) ⇒ <code>string</code>
|
|
59
|
+
* [.attach(namespace, obj)](#Entangld+attach)
|
|
60
|
+
* [.detach([namespace], [obj])](#Entangld+detach) ⇒ <code>boolean</code>
|
|
61
|
+
* [.transmit(func)](#Entangld+transmit)
|
|
62
|
+
* [.receive(msg, obj)](#Entangld+receive)
|
|
63
|
+
* [.push(path, data, [limit])](#Entangld+push)
|
|
64
|
+
* [.set(path, data, [operation_type], [params])](#Entangld+set)
|
|
65
|
+
* [.set_rpc(path, func, opts)](#Entangld+set_rpc)
|
|
66
|
+
* [.set_rpc_class(object, key_description_pairs, opts)](#Entangld+set_rpc_class)
|
|
67
|
+
* [.call_rpc(path, [args], [options])](#Entangld+call_rpc) ⇒ <code>Promise</code>
|
|
68
|
+
* [.get(path, [params], [options])](#Entangld+get) ⇒ <code>Promise</code>
|
|
69
|
+
* [.subscribe(path, func, [options])](#Entangld+subscribe) ⇒ <code>uuidv4</code>
|
|
70
|
+
* [.subscribed_to(subscription)](#Entangld+subscribed_to) ⇒ <code>Boolean</code>
|
|
71
|
+
* [.unsubscribe(path_or_uuid)](#Entangld+unsubscribe) ⇒ <code>number</code>
|
|
72
|
+
* [.unsubscribe_tree(path)](#Entangld+unsubscribe_tree)
|
|
73
|
+
|
|
74
|
+
<a name="Entangld+namespaces"></a>
|
|
75
|
+
|
|
76
|
+
### entangld.namespaces ⇒ <code>array</code>
|
|
77
|
+
Get namespaces
|
|
78
|
+
|
|
79
|
+
**Kind**: instance property of [<code>Entangld</code>](#Entangld)
|
|
80
|
+
**Returns**: <code>array</code> - namespaces - an array of attached namespaces
|
|
81
|
+
**Read only**: true
|
|
82
|
+
<a name="Entangld+subscriptions"></a>
|
|
83
|
+
|
|
84
|
+
### entangld.subscriptions ⇒ [<code>Array.<Subscription></code>](#Subscription)
|
|
85
|
+
Get list of subscriptions associated with this object
|
|
86
|
+
|
|
87
|
+
Note, this will include `head`, `terminal` and `pass through` subscriptions,
|
|
88
|
+
which can be checked using getter methods of the subscription object.
|
|
89
|
+
|
|
90
|
+
**Kind**: instance property of [<code>Entangld</code>](#Entangld)
|
|
91
|
+
**Returns**: [<code>Array.<Subscription></code>](#Subscription) - array of Subscriptions associated with this object
|
|
92
|
+
**Read only**: true
|
|
93
|
+
<a name="Entangld+namespace"></a>
|
|
94
|
+
|
|
95
|
+
### entangld.namespace() ⇒ <code>string</code>
|
|
96
|
+
Get namespace for a store
|
|
97
|
+
|
|
98
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
99
|
+
**Returns**: <code>string</code> - namespace for the given store
|
|
100
|
+
**Read only**: true
|
|
101
|
+
<a name="Entangld+attach"></a>
|
|
102
|
+
|
|
103
|
+
### entangld.attach(namespace, obj)
|
|
104
|
+
Attach a namespace and a store
|
|
105
|
+
|
|
106
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
107
|
+
**Throws**:
|
|
108
|
+
|
|
109
|
+
- <code>TypeError</code> if namespace/obj is null or empty.
|
|
110
|
+
- [<code>EntangldError</code>](#EntangldError) if you try to attach to the same namespace twice.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
| Param | Type | Description |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| namespace | <code>string</code> | a namespace for this store. |
|
|
116
|
+
| obj | <code>object</code> | an object that will be sent along with "transmit" callbacks when we need something from this store. |
|
|
117
|
+
|
|
118
|
+
<a name="Entangld+detach"></a>
|
|
119
|
+
|
|
120
|
+
### entangld.detach([namespace], [obj]) ⇒ <code>boolean</code>
|
|
121
|
+
Detach a namespace / obj pair.
|
|
122
|
+
|
|
123
|
+
If you only pass a namespace or a store, it will find the missing item
|
|
124
|
+
before detaching.
|
|
125
|
+
|
|
126
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
127
|
+
**Returns**: <code>boolean</code> - true if the element existed and was removed.
|
|
128
|
+
**Throws**:
|
|
129
|
+
|
|
130
|
+
- [<code>EntangldError</code>](#EntangldError) Error will be thrown if you don't pass at least
|
|
131
|
+
one parameter.
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
| Param | Type | Description |
|
|
135
|
+
| --- | --- | --- |
|
|
136
|
+
| [namespace] | <code>string</code> | the namespace. |
|
|
137
|
+
| [obj] | <code>object</code> | the store object. |
|
|
138
|
+
|
|
139
|
+
<a name="Entangld+transmit"></a>
|
|
140
|
+
|
|
141
|
+
### entangld.transmit(func)
|
|
142
|
+
Transmit
|
|
143
|
+
|
|
144
|
+
Specify a callback to be used so we can transmit data to another store.
|
|
145
|
+
Callback will be passed (message, obj) where 'message' is an
|
|
146
|
+
Entangld_Message object and obj is the object provided by attach().
|
|
147
|
+
|
|
148
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
149
|
+
**Throws**:
|
|
150
|
+
|
|
151
|
+
- <code>TypeError</code> if func is not a function.
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
| Param | Type | Description |
|
|
155
|
+
| --- | --- | --- |
|
|
156
|
+
| func | <code>function</code> | the callback function. |
|
|
157
|
+
|
|
158
|
+
<a name="Entangld+receive"></a>
|
|
159
|
+
|
|
160
|
+
### entangld.receive(msg, obj)
|
|
161
|
+
Receive
|
|
162
|
+
|
|
163
|
+
Call this function with the data that was sent via the transmit()
|
|
164
|
+
callback.
|
|
165
|
+
|
|
166
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
167
|
+
**Throws**:
|
|
168
|
+
|
|
169
|
+
- <code>ReferenceError</code> if event object was not provided.
|
|
170
|
+
- [<code>EntangldError</code>](#EntangldError) if an unknown message type was received.
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
| Param | Type | Description |
|
|
174
|
+
| --- | --- | --- |
|
|
175
|
+
| msg | [<code>Entangld\_Message</code>](#Entangld_Message) | the message to process. |
|
|
176
|
+
| obj | <code>object</code> | the attach() object where the message originted. |
|
|
177
|
+
|
|
178
|
+
<a name="Entangld+push"></a>
|
|
179
|
+
|
|
180
|
+
### entangld.push(path, data, [limit])
|
|
181
|
+
Push an object into an array in the store.
|
|
182
|
+
|
|
183
|
+
Convenience method for set(path, o, "push").
|
|
184
|
+
|
|
185
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
186
|
+
**Throws**:
|
|
187
|
+
|
|
188
|
+
- <code>TypeError</code> if path is not a string.
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
| Param | Type | Default | Description |
|
|
192
|
+
| --- | --- | --- | --- |
|
|
193
|
+
| path | <code>string</code> | | the path to set (like "system.fan.voltage"). |
|
|
194
|
+
| data | <code>object</code> | | the object or function you want to store at path. |
|
|
195
|
+
| [limit] | <code>number</code> | <code></code> | maximum size of the array. Older entries will be removed until the array size is less than or equal to limit. |
|
|
196
|
+
|
|
197
|
+
<a name="Entangld+set"></a>
|
|
198
|
+
|
|
199
|
+
### entangld.set(path, data, [operation_type], [params])
|
|
200
|
+
Set an object into the store
|
|
201
|
+
|
|
202
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
203
|
+
**Throws**:
|
|
204
|
+
|
|
205
|
+
- <code>TypeError</code> if path is not a string.
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
| Param | Type | Default | Description |
|
|
209
|
+
| --- | --- | --- | --- |
|
|
210
|
+
| path | <code>string</code> | | the path to set (like "system.fan.voltage"). |
|
|
211
|
+
| data | <code>object</code> | | the object or function you want to store at path. |
|
|
212
|
+
| [operation_type] | <code>string</code> | <code>"\"set\""</code> | whether to set or push the new data (push only works if the data item exists and is an array). |
|
|
213
|
+
| [params] | <code>object</code> | | additional parameters. |
|
|
214
|
+
|
|
215
|
+
<a name="Entangld+set_rpc"></a>
|
|
216
|
+
|
|
217
|
+
### entangld.set\_rpc(path, func, opts)
|
|
218
|
+
Set a function as an RPC in the datastore
|
|
219
|
+
|
|
220
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
221
|
+
**Throws**:
|
|
222
|
+
|
|
223
|
+
- <code>TypeError</code> if path is not a string.
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
| Param | Type | Default | Description |
|
|
227
|
+
| --- | --- | --- | --- |
|
|
228
|
+
| path | <code>string</code> | | the path to set (like "system.fan.voltage"). |
|
|
229
|
+
| func | <code>function</code> | | the function you want to store at path. |
|
|
230
|
+
| opts | <code>object</code> | | |
|
|
231
|
+
| [opts.description] | <code>string</code> | <code>null</code> | description for the function |
|
|
232
|
+
| [opts.function_string] | <code>string</code> | <code>null</code> | optional string of function source code to pass to parameter_parser |
|
|
233
|
+
|
|
234
|
+
<a name="Entangld+set_rpc_class"></a>
|
|
235
|
+
|
|
236
|
+
### entangld.set\_rpc\_class(object, key_description_pairs, opts)
|
|
237
|
+
Set a class instance as an RPC object in the datastore
|
|
238
|
+
|
|
239
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
240
|
+
**Throws**:
|
|
241
|
+
|
|
242
|
+
- <code>TypeError</code> if path is not a string.
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
| Param | Type | Default | Description |
|
|
246
|
+
| --- | --- | --- | --- |
|
|
247
|
+
| object | <code>\*</code> | | The object to attach |
|
|
248
|
+
| key_description_pairs | <code>Array</code> | | An array of key, description pairs |
|
|
249
|
+
| opts | <code>object</code> | | |
|
|
250
|
+
| [opts.description] | <code>string</code> | <code>null</code> | description for the function |
|
|
251
|
+
| [opts.function_string] | <code>string</code> | <code>null</code> | optional string of function source code to pass to parameter_parser |
|
|
252
|
+
|
|
253
|
+
<a name="Entangld+call_rpc"></a>
|
|
254
|
+
|
|
255
|
+
### entangld.call\_rpc(path, [args], [options]) ⇒ <code>Promise</code>
|
|
256
|
+
Call an RPC procedure in the datastore
|
|
257
|
+
|
|
258
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
259
|
+
**Returns**: <code>Promise</code> - promise resolving to return value of the rpc
|
|
260
|
+
**Throws**:
|
|
261
|
+
|
|
262
|
+
- [<code>RPCError</code>](#RPCError) if the rpc call experienced an error
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
| Param | Type | Default | Description |
|
|
266
|
+
| --- | --- | --- | --- |
|
|
267
|
+
| path | <code>string</code> | | the path to query (like "system.voltage"). |
|
|
268
|
+
| [args] | <code>Array</code> | <code>[]</code> | the arguments to pass to the RPC. |
|
|
269
|
+
| [options] | <code>object</code> | | |
|
|
270
|
+
| [options.timeout_ms] | <code>number</code> | | reject with an EntangldTimeoutError if no reply arrives within this many milliseconds. This stops the wait, not the RPC, which may still run. Omit to wait indefinitely. |
|
|
271
|
+
| [options.signal] | <code>AbortSignal</code> | | reject with signal.reason when this aborts. This also stops the wait, not the RPC. |
|
|
272
|
+
|
|
273
|
+
<a name="Entangld+get"></a>
|
|
274
|
+
|
|
275
|
+
### entangld.get(path, [params], [options]) ⇒ <code>Promise</code>
|
|
276
|
+
Get an object from the store.
|
|
277
|
+
|
|
278
|
+
Note: using max_depth, especially large max_depth, involves a lot of
|
|
279
|
+
recursion and may be expensive.
|
|
280
|
+
|
|
281
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
282
|
+
**Returns**: <code>Promise</code> - promise resolving to the object at that path.
|
|
283
|
+
**Throws**:
|
|
284
|
+
|
|
285
|
+
- <code>TypeError</code> if path is not a string, timeout_ms is not a
|
|
286
|
+
positive number of at most 2147483647, or signal is not an AbortSignal.
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
| Param | Type | Description |
|
|
290
|
+
| --- | --- | --- |
|
|
291
|
+
| path | <code>string</code> | the path to query (like "system.voltage"). |
|
|
292
|
+
| [params] | <code>object</code> | the parameters to be passed to the remote function (RPC) or the maximum depth of the returned object (normal mode). |
|
|
293
|
+
| [options] | <code>object</code> | |
|
|
294
|
+
| [options.timeout_ms] | <code>number</code> | reject with an EntangldTimeoutError if no value arrives within this many milliseconds. Applies to remote paths and to local functions. It is never sent to a remote store. Omit to wait indefinitely. |
|
|
295
|
+
| [options.signal] | <code>AbortSignal</code> | reject with signal.reason when this aborts. If it has already aborted, nothing is sent and no function is called. This only stops the wait, not any work a remote store or local function has started. |
|
|
296
|
+
|
|
297
|
+
<a name="Entangld+subscribe"></a>
|
|
298
|
+
|
|
299
|
+
### entangld.subscribe(path, func, [options]) ⇒ <code>uuidv4</code>
|
|
300
|
+
Subscribe to change events for a path
|
|
301
|
+
|
|
302
|
+
If objects at or below this path change, you will get a callback
|
|
303
|
+
|
|
304
|
+
Subscriptions to keys within attach()ed stores are remote subscriptions.
|
|
305
|
+
If several stores are attached in some kind of arrangement, a given key
|
|
306
|
+
may actually traverse multiple stores! Since each store only knows its
|
|
307
|
+
immediate neighbors - and has no introspection into those neighbors - each
|
|
308
|
+
store is only able to keeps track of the neighbor on each side with
|
|
309
|
+
respect to a particular path and has no knowledge of the eventual
|
|
310
|
+
endpoints. This means that subscribing across several datstores is accomplished
|
|
311
|
+
by daisy-chaining 2-way subscriptions across each datastore interface.
|
|
312
|
+
|
|
313
|
+
For example, let's suppose capital letters represent Entangld stores and
|
|
314
|
+
lowercase letters are actual objects. Then the path "A.B.c.d.E.F.g.h"
|
|
315
|
+
will represent a subscription that traverses four Entangld stores.
|
|
316
|
+
From the point of view of a store in the middle - say, E - the "upstream"
|
|
317
|
+
is B and the "downstream" is F.
|
|
318
|
+
|
|
319
|
+
Each store involved keeps track of any subscriptions with which it is
|
|
320
|
+
involved. It tracks the upstream and downstream, and the uuid of the
|
|
321
|
+
subscription. The uuid is the same across all stores for a given
|
|
322
|
+
subscription. For a particular store, the upstream is null if it is the
|
|
323
|
+
original link in the chain (called the `head`), and the downstream is
|
|
324
|
+
null if this store owns the endpoint value (called the `tail`). Any
|
|
325
|
+
subscription which is not the head of a chain is called a `pass through`
|
|
326
|
+
subscription, because it exist only to pass `event` messages back up the
|
|
327
|
+
chain to the head (where the user-provided callback function exists).
|
|
328
|
+
subscriptions can be checked to see if they are `pass through` type via
|
|
329
|
+
the getter `sub.is_pass_through`.
|
|
330
|
+
|
|
331
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
332
|
+
**Returns**: <code>uuidv4</code> - - the uuid of the subscription
|
|
333
|
+
**Throws**:
|
|
334
|
+
|
|
335
|
+
- <code>TypeError</code> if path is not a string, or signal is not an AbortSignal.
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
| Param | Type | Default | Description |
|
|
339
|
+
| --- | --- | --- | --- |
|
|
340
|
+
| path | <code>string</code> | | the path to watch. Use of '*' is allowed as a wildcard (e.g. "system.*") |
|
|
341
|
+
| func | <code>function</code> | | the callback - will be of the form (path, value). |
|
|
342
|
+
| [options] | <code>number</code> \| <code>null</code> \| <code>object</code> | <code></code> | an options object, or the value of options.every. |
|
|
343
|
+
| [options.every] | <code>number</code> \| <code>null</code> | <code></code> | the number of `set` messages to wait before calling callback |
|
|
344
|
+
| [options.signal] | <code>AbortSignal</code> | | unsubscribe when this aborts. If it has already aborted, no subscription is created. The uuid is still returned, as it would be for a subscription which has since ended. Calling unsubscribe() after an abort throws, see unsubscribe(). |
|
|
345
|
+
|
|
346
|
+
<a name="Entangld+subscribed_to"></a>
|
|
347
|
+
|
|
348
|
+
### entangld.subscribed\_to(subscription) ⇒ <code>Boolean</code>
|
|
349
|
+
Check for subscription
|
|
350
|
+
|
|
351
|
+
Are we subscribed to a particular remote path?
|
|
352
|
+
|
|
353
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
354
|
+
**Returns**: <code>Boolean</code> - true if we are subscribed.
|
|
355
|
+
|
|
356
|
+
| Param | Type | Description |
|
|
357
|
+
| --- | --- | --- |
|
|
358
|
+
| subscription | <code>String</code> | the subscription to check for. |
|
|
359
|
+
|
|
360
|
+
<a name="Entangld+unsubscribe"></a>
|
|
361
|
+
|
|
362
|
+
### entangld.unsubscribe(path_or_uuid) ⇒ <code>number</code>
|
|
363
|
+
Unubscribe to change events for a given path or uuid.
|
|
364
|
+
|
|
365
|
+
Caution - if a path is provided, _all_ events belonging to you with that
|
|
366
|
+
path will be deleted, so if you have multiple subscriptions on a single path,
|
|
367
|
+
and only want one of them to be removed, you must provide the uuid instead.
|
|
368
|
+
|
|
369
|
+
Caution - this throws if the subscription has already ended. That includes
|
|
370
|
+
a subscription ended by its signal, or a signal which had already aborted
|
|
371
|
+
when subscribe() was called. If you mix signals with explicit unsubscribes,
|
|
372
|
+
check `signal.aborted` first or catch the error.
|
|
373
|
+
|
|
374
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
375
|
+
**Returns**: <code>number</code> - count of subscriptions removed.
|
|
376
|
+
**Throws**:
|
|
377
|
+
|
|
378
|
+
- [<code>EntangldError</code>](#EntangldError) if no subscriptions were found.
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
| Param | Type | Description |
|
|
382
|
+
| --- | --- | --- |
|
|
383
|
+
| path_or_uuid | <code>String</code> \| <code>uuidv4</code> | the path (or uuid) to unwatch. |
|
|
384
|
+
|
|
385
|
+
<a name="Entangld+unsubscribe_tree"></a>
|
|
386
|
+
|
|
387
|
+
### entangld.unsubscribe\_tree(path)
|
|
388
|
+
Unsubscribe tree.
|
|
389
|
+
|
|
390
|
+
Remove any subscriptions that are beneath a path.
|
|
391
|
+
|
|
392
|
+
**Kind**: instance method of [<code>Entangld</code>](#Entangld)
|
|
393
|
+
**Throws**:
|
|
394
|
+
|
|
395
|
+
- [<code>EntangldError</code>](#EntangldError) error if there are stores we cannot detach
|
|
396
|
+
(i.e. they belong to someone else / upstream != null)
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
| Param | Type | Description |
|
|
400
|
+
| --- | --- | --- |
|
|
401
|
+
| path | <code>string</code> | the tree to unwatch. |
|
|
402
|
+
|
|
403
|
+
<a name="EntangldError"></a>
|
|
404
|
+
|
|
405
|
+
## EntangldError
|
|
406
|
+
Error class for Entangld.
|
|
407
|
+
|
|
408
|
+
**Kind**: global class
|
|
409
|
+
<a name="EntangldTimeoutError"></a>
|
|
410
|
+
|
|
411
|
+
## EntangldTimeoutError ⇐ [<code>EntangldError</code>](#EntangldError)
|
|
412
|
+
Error for a request which got no reply in time.
|
|
413
|
+
|
|
414
|
+
**Kind**: global class
|
|
415
|
+
**Extends**: [<code>EntangldError</code>](#EntangldError)
|
|
416
|
+
<a name="RPCError"></a>
|
|
417
|
+
|
|
418
|
+
## RPCError
|
|
419
|
+
Remote Error class for Entangld.
|
|
420
|
+
|
|
421
|
+
**Kind**: global class
|
|
422
|
+
<a name="Entangld_Message"></a>
|
|
423
|
+
|
|
424
|
+
## Entangld\_Message
|
|
425
|
+
Message class for Entangld.
|
|
426
|
+
|
|
427
|
+
These messages are used for executing datastore operations between
|
|
428
|
+
remote datastores. In these relationships, there is always an upstream
|
|
429
|
+
and downstream pair, so that `get`, `set`, `push`, `subscribe` and `unsubscribe`
|
|
430
|
+
messages are created upstream and passed downstream while `event` and `value`
|
|
431
|
+
messages are created downstream and are passed back up. To maintain consistency,
|
|
432
|
+
the internal `.path` attribute
|
|
433
|
+
will always refer a path relative to the downstream datastore, since the
|
|
434
|
+
downstream datastores do not necessarilly have access to the upstream store
|
|
435
|
+
structure, and so cannot generally construct upstream paths. This means that
|
|
436
|
+
the `.path` attribute is a `tree` relative to the upstream datastore, and
|
|
437
|
+
the upstream path can be reconstructed as:
|
|
438
|
+
```js
|
|
439
|
+
upstream._namespaces.get(downstream) + "." + msg.path;
|
|
440
|
+
```
|
|
441
|
+
Since `unsubscribe` messages identify a subscription by its `.uuid`, they should
|
|
442
|
+
have their `.path` attributes set to undefined or null.
|
|
443
|
+
|
|
444
|
+
Most messages will also have a `.uuid` attribute. For `get`/`value` messages,
|
|
445
|
+
this allows for the value to be properly linked back up with the original `get`
|
|
446
|
+
message. For the `subscribe`/`unsubscribe`/`event` messages, this allows for
|
|
447
|
+
callback functions to be trigger properly, and for unsubscribe messages to
|
|
448
|
+
propogate down the chain. `set`/`push` messages do not use the `.uuid` attribute
|
|
449
|
+
since they require no response.
|
|
450
|
+
|
|
451
|
+
**Kind**: global class
|
|
452
|
+
|
|
453
|
+
* [Entangld_Message](#Entangld_Message)
|
|
454
|
+
* [.get(tree, [get_params])](#Entangld_Message.get) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
455
|
+
* [.value(get_msg, value)](#Entangld_Message.value) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
456
|
+
* [.setpush(obj)](#Entangld_Message.setpush) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
457
|
+
* [.subscribe(tree, uuid)](#Entangld_Message.subscribe) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
458
|
+
* [.event(path, value, uuid)](#Entangld_Message.event) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
459
|
+
* [.unsubscribe(uuid)](#Entangld_Message.unsubscribe)
|
|
460
|
+
|
|
461
|
+
<a name="Entangld_Message.get"></a>
|
|
462
|
+
|
|
463
|
+
### Entangld_Message.get(tree, [get_params]) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
464
|
+
Create a `get` message for remote datastores
|
|
465
|
+
|
|
466
|
+
**Kind**: static method of [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
467
|
+
**Returns**: [<code>Entangld\_Message</code>](#Entangld_Message) - - The get message to pass to the remote datastore
|
|
468
|
+
|
|
469
|
+
| Param | Type | Description |
|
|
470
|
+
| --- | --- | --- |
|
|
471
|
+
| tree | <code>string</code> | the path relative to the remote datastore |
|
|
472
|
+
| [get_params] | <code>\*</code> | any parameters to be passed to the remote datastore's local get function |
|
|
473
|
+
|
|
474
|
+
<a name="Entangld_Message.value"></a>
|
|
475
|
+
|
|
476
|
+
### Entangld_Message.value(get_msg, value) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
477
|
+
Create a `value` message in response to a `get` message
|
|
478
|
+
|
|
479
|
+
**Kind**: static method of [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
480
|
+
**Returns**: [<code>Entangld\_Message</code>](#Entangld_Message) - - The `value` message to pass back
|
|
481
|
+
|
|
482
|
+
| Param | Type | Description |
|
|
483
|
+
| --- | --- | --- |
|
|
484
|
+
| get_msg | [<code>Entangld\_Message</code>](#Entangld_Message) | the `get` message which this is in response to |
|
|
485
|
+
| value | | the value of the `get` |
|
|
486
|
+
|
|
487
|
+
<a name="Entangld_Message.setpush"></a>
|
|
488
|
+
|
|
489
|
+
### Entangld_Message.setpush(obj) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
490
|
+
Create a `set`/`push` message for a remote datastore
|
|
491
|
+
|
|
492
|
+
**Kind**: static method of [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
493
|
+
**Returns**: [<code>Entangld\_Message</code>](#Entangld_Message) - - the "set" or "push" message
|
|
494
|
+
|
|
495
|
+
| Param | Type | Description |
|
|
496
|
+
| --- | --- | --- |
|
|
497
|
+
| obj | <code>Object</code> | The parameter object for the set/push |
|
|
498
|
+
| obj.type | <code>string</code> | either "set" or "push" |
|
|
499
|
+
| obj.tree | <code>string</code> | the path (relative to the downstream datastore) |
|
|
500
|
+
| obj.value | <code>\*</code> | the value to insert into the datastore |
|
|
501
|
+
| obj.params | <code>\*</code> | any additional parameters |
|
|
502
|
+
|
|
503
|
+
<a name="Entangld_Message.subscribe"></a>
|
|
504
|
+
|
|
505
|
+
### Entangld_Message.subscribe(tree, uuid) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
506
|
+
Construct subscribe message
|
|
507
|
+
|
|
508
|
+
**Kind**: static method of [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
509
|
+
**Returns**: [<code>Entangld\_Message</code>](#Entangld_Message) - the `subscribe` message
|
|
510
|
+
|
|
511
|
+
| Param | Type | Description |
|
|
512
|
+
| --- | --- | --- |
|
|
513
|
+
| tree | <code>string</code> | the path (relative to the downstream datastore) |
|
|
514
|
+
| uuid | <code>uuidv4</code> | the subscription uuid |
|
|
515
|
+
|
|
516
|
+
<a name="Entangld_Message.event"></a>
|
|
517
|
+
|
|
518
|
+
### Entangld_Message.event(path, value, uuid) ⇒ [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
519
|
+
Create an `event` message to return data to subscribe callbacks
|
|
520
|
+
|
|
521
|
+
**Kind**: static method of [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
522
|
+
**Returns**: [<code>Entangld\_Message</code>](#Entangld_Message) - the `event` message
|
|
523
|
+
|
|
524
|
+
| Param | Type | Description |
|
|
525
|
+
| --- | --- | --- |
|
|
526
|
+
| path | <code>string</code> | the path (relative to the downstream store) |
|
|
527
|
+
| value | <code>\*</code> | the updated datastore value at the path |
|
|
528
|
+
| uuid | <code>uuidv4</code> | the uuid of the subscribe being triggered |
|
|
529
|
+
|
|
530
|
+
<a name="Entangld_Message.unsubscribe"></a>
|
|
531
|
+
|
|
532
|
+
### Entangld_Message.unsubscribe(uuid)
|
|
533
|
+
Create an unsubscribe message for a subscription uuid
|
|
534
|
+
|
|
535
|
+
**Kind**: static method of [<code>Entangld\_Message</code>](#Entangld_Message)
|
|
536
|
+
|
|
537
|
+
| Param | Type | Description |
|
|
538
|
+
| --- | --- | --- |
|
|
539
|
+
| uuid | <code>String</code> | the subscription uuid |
|
|
540
|
+
|
|
541
|
+
<a name="Subscription"></a>
|
|
542
|
+
|
|
543
|
+
## Subscription
|
|
544
|
+
A datastore subscription object
|
|
545
|
+
|
|
546
|
+
**Kind**: global class
|
|
547
|
+
|
|
548
|
+
* [Subscription](#Subscription)
|
|
549
|
+
* [new Subscription(obj)](#new_Subscription_new)
|
|
550
|
+
* [.is_pass_through](#Subscription+is_pass_through) ⇒ <code>Boolean</code>
|
|
551
|
+
* [.is_terminal](#Subscription+is_terminal) ⇒ <code>Boolean</code>
|
|
552
|
+
* [.is_head](#Subscription+is_head) ⇒ <code>Boolean</code>
|
|
553
|
+
* [.has_downstream](#Subscription+has_downstream) ⇒ <code>Boolean</code>
|
|
554
|
+
* [.has_upstream](#Subscription+has_upstream) ⇒ <code>Boolean</code>
|
|
555
|
+
* [.watch_signal(signal, on_abort)](#Subscription+watch_signal)
|
|
556
|
+
* [.unwatch_signal()](#Subscription+unwatch_signal)
|
|
557
|
+
* [.call()](#Subscription+call)
|
|
558
|
+
* [.matches_subscription(sub)](#Subscription+matches_subscription) ⇒ <code>Boolean</code>
|
|
559
|
+
* [.matches_event_message(msg)](#Subscription+matches_event_message) ⇒ <code>Boolean</code>
|
|
560
|
+
* [.matches_unsubscribe_message(msg)](#Subscription+matches_unsubscribe_message) ⇒ <code>Boolean</code>
|
|
561
|
+
* [.matches_path(path)](#Subscription+matches_path) ⇒ <code>Boolean</code>
|
|
562
|
+
* [.matches_uuid(uuid)](#Subscription+matches_uuid) ⇒ <code>Boolean</code>
|
|
563
|
+
* [.is_beneath(path)](#Subscription+is_beneath) ⇒ <code>Boolean</code>
|
|
564
|
+
* [.is_above(path)](#Subscription+is_above) ⇒ <code>Boolean</code>
|
|
565
|
+
* [.static_copy()](#Subscription+static_copy) ⇒ [<code>Subscription</code>](#Subscription)
|
|
566
|
+
|
|
567
|
+
<a name="new_Subscription_new"></a>
|
|
568
|
+
|
|
569
|
+
### new Subscription(obj)
|
|
570
|
+
Constructor
|
|
571
|
+
|
|
572
|
+
**Returns**: [<code>Subscription</code>](#Subscription) - - the subscription object
|
|
573
|
+
|
|
574
|
+
| Param | Type | Description |
|
|
575
|
+
| --- | --- | --- |
|
|
576
|
+
| obj | <code>Object</code> | the configuration object |
|
|
577
|
+
| obj.path | <code>string</code> | the datastore path (relative to this datastore) of the subscription |
|
|
578
|
+
| obj.uuid | <code>uuidv4</code> | the uuid of the subscription chain |
|
|
579
|
+
| obj.callback | <code>function</code> | the callback function, with signature (path, value), where path is relative to this datastore |
|
|
580
|
+
| obj.downstream | [<code>Entangld</code>](#Entangld) \| <code>null</code> | the downstream datastore (if any) associated with this subscription |
|
|
581
|
+
| obj.upstream | [<code>Entangld</code>](#Entangld) \| <code>null</code> | the upstream datastore (if any) associated with this subscription |
|
|
582
|
+
| obj.every | <code>number</code> \| <code>null</code> | how many `set` messages to wait before calling callback |
|
|
583
|
+
|
|
584
|
+
<a name="Subscription+is_pass_through"></a>
|
|
585
|
+
|
|
586
|
+
### subscription.is\_pass\_through ⇒ <code>Boolean</code>
|
|
587
|
+
Check if subscription is a `pass through` type
|
|
588
|
+
|
|
589
|
+
Pass throughs are as the links in a chain of subscriptions to allows
|
|
590
|
+
subscriptions to remote datastores. One store acts as the `head`, where
|
|
591
|
+
the callback function is registered, an all others are `path through` datastores
|
|
592
|
+
which simply pass event messages back up to the head subscription.
|
|
593
|
+
|
|
594
|
+
**Kind**: instance property of [<code>Subscription</code>](#Subscription)
|
|
595
|
+
<a name="Subscription+is_terminal"></a>
|
|
596
|
+
|
|
597
|
+
### subscription.is\_terminal ⇒ <code>Boolean</code>
|
|
598
|
+
Check if this subscription will be directly given data by a datastore
|
|
599
|
+
|
|
600
|
+
**Kind**: instance property of [<code>Subscription</code>](#Subscription)
|
|
601
|
+
<a name="Subscription+is_head"></a>
|
|
602
|
+
|
|
603
|
+
### subscription.is\_head ⇒ <code>Boolean</code>
|
|
604
|
+
Check if this subscription will apply a user-supplied callback to data
|
|
605
|
+
|
|
606
|
+
**Kind**: instance property of [<code>Subscription</code>](#Subscription)
|
|
607
|
+
<a name="Subscription+has_downstream"></a>
|
|
608
|
+
|
|
609
|
+
### subscription.has\_downstream ⇒ <code>Boolean</code>
|
|
610
|
+
Check if subscription has any downstream subscriptions
|
|
611
|
+
|
|
612
|
+
It the subscription refers to a remote datastore (the downstream), this
|
|
613
|
+
getter will return a true. Note that !this.has_downstream will check if
|
|
614
|
+
the subscription is the `tail` subscription object in a subscription chain.
|
|
615
|
+
|
|
616
|
+
**Kind**: instance property of [<code>Subscription</code>](#Subscription)
|
|
617
|
+
<a name="Subscription+has_upstream"></a>
|
|
618
|
+
|
|
619
|
+
### subscription.has\_upstream ⇒ <code>Boolean</code>
|
|
620
|
+
Check if subscription has any upstream subscriptions
|
|
621
|
+
|
|
622
|
+
It the subscription passes data back to a remote datastore (the upstream), this
|
|
623
|
+
getter will return a true.
|
|
624
|
+
|
|
625
|
+
**Kind**: instance property of [<code>Subscription</code>](#Subscription)
|
|
626
|
+
<a name="Subscription+watch_signal"></a>
|
|
627
|
+
|
|
628
|
+
### subscription.watch\_signal(signal, on_abort)
|
|
629
|
+
Run a callback when a signal aborts
|
|
630
|
+
|
|
631
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
632
|
+
|
|
633
|
+
| Param | Type | Description |
|
|
634
|
+
| --- | --- | --- |
|
|
635
|
+
| signal | <code>AbortSignal</code> | the signal to watch |
|
|
636
|
+
| on_abort | <code>function</code> | the callback |
|
|
637
|
+
|
|
638
|
+
<a name="Subscription+unwatch_signal"></a>
|
|
639
|
+
|
|
640
|
+
### subscription.unwatch\_signal()
|
|
641
|
+
Stop watching this subscription's signal, if it has one
|
|
642
|
+
|
|
643
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
644
|
+
<a name="Subscription+call"></a>
|
|
645
|
+
|
|
646
|
+
### subscription.call()
|
|
647
|
+
Apply this callback function
|
|
648
|
+
|
|
649
|
+
Note, this method also tracks the number of times that a callback
|
|
650
|
+
function is called (if this subscription is terminal), so that if
|
|
651
|
+
the subscriptions are throttled by specifying an `this.every`,
|
|
652
|
+
this method will only call the callback function every `this.every`
|
|
653
|
+
times it receives a `set` message. If this subscription is not
|
|
654
|
+
terminal, then the callback function is called every time.
|
|
655
|
+
|
|
656
|
+
This method also is safed when a callback function is not give (i.e.
|
|
657
|
+
by the `this.static_copy()` method).
|
|
658
|
+
|
|
659
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
660
|
+
<a name="Subscription+matches_subscription"></a>
|
|
661
|
+
|
|
662
|
+
### subscription.matches\_subscription(sub) ⇒ <code>Boolean</code>
|
|
663
|
+
Check if a different `Subscription` object matches this subscription
|
|
664
|
+
|
|
665
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
666
|
+
**Returns**: <code>Boolean</code> - - True if the subscriptions match
|
|
667
|
+
|
|
668
|
+
| Param | Type | Description |
|
|
669
|
+
| --- | --- | --- |
|
|
670
|
+
| sub | [<code>Subscription</code>](#Subscription) | a different subscription |
|
|
671
|
+
|
|
672
|
+
<a name="Subscription+matches_event_message"></a>
|
|
673
|
+
|
|
674
|
+
### subscription.matches\_event\_message(msg) ⇒ <code>Boolean</code>
|
|
675
|
+
Check if an `event` message matches this subscription
|
|
676
|
+
|
|
677
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
678
|
+
**Returns**: <code>Boolean</code> - - True if the message is associated with the subscription
|
|
679
|
+
|
|
680
|
+
| Param | Type | Description |
|
|
681
|
+
| --- | --- | --- |
|
|
682
|
+
| msg | [<code>Entangld\_Message</code>](#Entangld_Message) | a received message from a downstream datastore |
|
|
683
|
+
|
|
684
|
+
<a name="Subscription+matches_unsubscribe_message"></a>
|
|
685
|
+
|
|
686
|
+
### subscription.matches\_unsubscribe\_message(msg) ⇒ <code>Boolean</code>
|
|
687
|
+
Check if an `unsubscribe` message matches this subscription
|
|
688
|
+
|
|
689
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
690
|
+
**Returns**: <code>Boolean</code> - - True if the message is associated with the subscription
|
|
691
|
+
|
|
692
|
+
| Param | Type | Description |
|
|
693
|
+
| --- | --- | --- |
|
|
694
|
+
| msg | [<code>Entangld\_Message</code>](#Entangld_Message) | a received message from a downstream datastore |
|
|
695
|
+
|
|
696
|
+
<a name="Subscription+matches_path"></a>
|
|
697
|
+
|
|
698
|
+
### subscription.matches\_path(path) ⇒ <code>Boolean</code>
|
|
699
|
+
Check if a provided path matches this path
|
|
700
|
+
|
|
701
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
702
|
+
**Returns**: <code>Boolean</code> - - true if the path matches
|
|
703
|
+
|
|
704
|
+
| Param | Type | Description |
|
|
705
|
+
| --- | --- | --- |
|
|
706
|
+
| path | <code>String</code> | a path string to check against |
|
|
707
|
+
|
|
708
|
+
<a name="Subscription+matches_uuid"></a>
|
|
709
|
+
|
|
710
|
+
### subscription.matches\_uuid(uuid) ⇒ <code>Boolean</code>
|
|
711
|
+
Check if a provided uuid matches this uuid
|
|
712
|
+
|
|
713
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
714
|
+
**Returns**: <code>Boolean</code> - - true if the path matches
|
|
715
|
+
|
|
716
|
+
| Param | Type | Description |
|
|
717
|
+
| --- | --- | --- |
|
|
718
|
+
| uuid | <code>uuidv4</code> | a uuid string to check against |
|
|
719
|
+
|
|
720
|
+
<a name="Subscription+is_beneath"></a>
|
|
721
|
+
|
|
722
|
+
### subscription.is\_beneath(path) ⇒ <code>Boolean</code>
|
|
723
|
+
Check if subscription path is beneath a provided path
|
|
724
|
+
|
|
725
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
726
|
+
**Returns**: <code>Boolean</code> - - true if the subscription is beneath the path
|
|
727
|
+
|
|
728
|
+
| Param | Type | Description |
|
|
729
|
+
| --- | --- | --- |
|
|
730
|
+
| path | <code>String</code> | a path string to check against |
|
|
731
|
+
|
|
732
|
+
<a name="Subscription+is_above"></a>
|
|
733
|
+
|
|
734
|
+
### subscription.is\_above(path) ⇒ <code>Boolean</code>
|
|
735
|
+
Check if subscription path is above a provided path
|
|
736
|
+
|
|
737
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
738
|
+
**Returns**: <code>Boolean</code> - - true if the subscription is beneath the path
|
|
739
|
+
|
|
740
|
+
| Param | Type | Description |
|
|
741
|
+
| --- | --- | --- |
|
|
742
|
+
| path | <code>String</code> | a path string to check against |
|
|
743
|
+
|
|
744
|
+
<a name="Subscription+static_copy"></a>
|
|
745
|
+
|
|
746
|
+
### subscription.static\_copy() ⇒ [<code>Subscription</code>](#Subscription)
|
|
747
|
+
Get a copy of this subscription without external references
|
|
748
|
+
|
|
749
|
+
This creates a copy, except the upstream/downstream references
|
|
750
|
+
are set to true (if they exist) or null (if they don't. Addtionally,
|
|
751
|
+
the callback function is excluded.
|
|
752
|
+
|
|
753
|
+
**Kind**: instance method of [<code>Subscription</code>](#Subscription)
|
|
754
|
+
**Returns**: [<code>Subscription</code>](#Subscription) - a copy of this subscription object
|