@graffy/core 0.15.8-alpha.5 → 0.15.8

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 (3) hide show
  1. package/index.cjs +231 -1
  2. package/index.mjs +226 -1
  3. package/package.json +4 -4
package/index.cjs CHANGED
@@ -1 +1,231 @@
1
- "use strict";var t=require("@graffy/common"),r=require("@graffy/stream"),e=require("debug"),n=require("@graffy/testing");function a(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}function o(t){return t&&"object"==typeof t&&!Array.isArray(t)}function i(...r){if(1===r.length)return[[],r[0],{}];if(2===r.length){if(o(r[0])){if(!o(r[1]))throw Error(`validateCall.invalid_options: ${JSON.stringify(r[1])}`);return[[],r[0],r[1]]}return[t.encodePath(r[0]),r[1],{}]}if(3===r.length){if(!o(r[2]))throw Error(`validateCall.invalid_options: ${JSON.stringify(r[1])}`);return[t.encodePath(r[0]),r[1],r[2]]}throw Error(`validateCall.invalid_args: ${JSON.stringify(r)}`)}function c(...r){if(1===r.length){if("function"!=typeof r[0])throw Error(`validateOn.invalid_handler: ${JSON.stringify(r[0])}`);return[[],r[0]]}if(2===r.length){if("function"!=typeof r[1])throw Error(`validateOn.invalid_handler: ${JSON.stringify(r[1])}`);return[t.encodePath(r[0]),r[1]]}throw Error(`validateOn.invalid_args: ${JSON.stringify(r)}`)}function s(r,e){return async function(n,a,o){let i,c=!1;const s=t.unwrap(n,e),h=t.remove(n,e)||[];const l=await r(s,a,(async function(r){c=!0;const n=t.wrap(r,e);h.length&&t.merge(n,h);const a=await o(n);return i=t.remove(a,e)||[],t.unwrap(a,e)})),u=t.wrap(l,e);return!c&&h.length&&(i=await o(h)),i&&i.length&&t.merge(u,i),u}}const h=a(e).default("graffy:core");class l{constructor(){this.handlers={}}on(t,r,e){this.handlers[t]=this.handlers[t]||[],this.handlers[t].push({path:r,handle:e})}call(r,e,a={}){return h("call",r,n.format(e)),function(r,e,n){if(!r||!r.length)throw Error("resolve.no_provider");return function e(a,o){if(a>=r.length)throw Error("resolve.no_providers_for "+JSON.stringify(o));const{path:i,handle:c}=r[a];if(!t.unwrap(o,i))return e(a+1,o);let s=!1;return c(o,n,(t=>{if(s)throw Error("resolve.duplicate_next_call: "+r[a].name);if(void 0===t)throw Error("resolve.next_without_payload: "+r[a].name);return s=!0,e(a+1,t)}))}(0,e)}(this.handlers[r],e,a)}}class u{constructor(t=[],r=new l){this.core=r,this.path=t}on(t,...r){const[e,n]=c(...r),a=this.path.concat(e);this.core.on(t,a,n)}onRead(...r){const[e,n]=c(...r),a=this.path.concat(e);this.core.on("read",a,s((async function(r,e){const a=t.decodeQuery(r),o=t.encodeGraph(await n(a,e));return t.finalize(o,r)}),a))}onWatch(...e){const[n,a]=c(...e),o=this.path.concat(n);this.core.on("watch",o,function(e,n){return async function*(a,o,i){let c,s=!1;const h=t.unwrap(a,n),l=t.remove(a,n)||[],u=e(h,o,(async function*(e){s=!0;const a=t.wrap(e,n);let o;l.length&&t.merge(a,l),c=r.makeStream((t=>{o=t}));for await(const r of i(a)){const e=t.unwrap(r,n),a=t.remove(r,n);a&&o(a),e&&(yield e)}})),f=await(await u.next()).value,d=r.makeStream((r=>(r(t.wrap(f,n)),async function(t,r){for await(const e of t)r(e)}(u,(e=>{r(t.wrap(e,n))})),()=>u.return())));!s&&l.length&&(c=i(l)),yield*c?t.mergeStreams(d,c):d}}((function(e,n){return r.makeStream(((r,o)=>{const i=a(t.decodeQuery(e),n);return async function(){try{let n=(await i.next()).value;r(n&&t.finalize(t.encodeGraph(n),e));for await(const e of i)r(e&&t.encodeGraph(e))}catch(n){o(n)}}(),()=>i.return()}))}),o))}onWrite(...r){const[e,n]=c(...r),a=this.path.concat(e);this.core.on("write",a,s((async function(r,e){return t.encodeGraph(await n(t.decodeGraph(r),e))}),a))}use(...t){const[r,e]=c(...t);e(new u(r,this.core))}call(t,r,e={}){return this.core.call(t,r,e)}async read(...r){const[e,n,a]=i(...r),o=t.wrapObject(n,e),c=t.encodeQuery(o),s=await this.core.call("read",c,a||{});return t.unwrapObject(t.decorate(s,o),t.decodePath(e))}watch(...e){const[n,a,o]=i(...e),c=t.wrapObject(a,n),s=t.encodeQuery(c),h=this.core.call("watch",s,o||{});return r.mapStream(h,(r=>t.unwrapObject(t.decorate(r,c),t.decodePath(n))))}async write(...r){const[e,n,a]=i(...r),o=t.wrap(t.encodeGraph(n),e),c=await this.core.call("write",o,a||{});return t.unwrapObject(t.decodeGraph(c),t.decodePath(e))}}module.exports=u;
1
+ "use strict";
2
+ var common = require("@graffy/common");
3
+ var stream = require("@graffy/stream");
4
+ var debug = require("debug");
5
+ var testing = require("@graffy/testing");
6
+ function _interopDefaultLegacy(e) {
7
+ return e && typeof e === "object" && "default" in e ? e : { "default": e };
8
+ }
9
+ var debug__default = /* @__PURE__ */ _interopDefaultLegacy(debug);
10
+ function isPlainObject(obj) {
11
+ return obj && typeof obj === "object" && !Array.isArray(obj);
12
+ }
13
+ function validateCall(...args) {
14
+ if (args.length === 1) {
15
+ return [[], args[0], {}];
16
+ } else if (args.length === 2) {
17
+ if (isPlainObject(args[0])) {
18
+ if (!isPlainObject(args[1])) {
19
+ throw Error(`validateCall.invalid_options: ${JSON.stringify(args[1])}`);
20
+ }
21
+ return [[], args[0], args[1]];
22
+ } else {
23
+ return [common.encodePath(args[0]), args[1], {}];
24
+ }
25
+ } else if (args.length === 3) {
26
+ if (!isPlainObject(args[2])) {
27
+ throw Error(`validateCall.invalid_options: ${JSON.stringify(args[1])}`);
28
+ }
29
+ return [common.encodePath(args[0]), args[1], args[2]];
30
+ }
31
+ throw Error(`validateCall.invalid_args: ${JSON.stringify(args)}`);
32
+ }
33
+ function validateOn(...args) {
34
+ if (args.length === 1) {
35
+ if (typeof args[0] !== "function") {
36
+ throw Error(`validateOn.invalid_handler: ${JSON.stringify(args[0])}`);
37
+ }
38
+ return [[], args[0]];
39
+ } else if (args.length === 2) {
40
+ if (typeof args[1] !== "function") {
41
+ throw Error(`validateOn.invalid_handler: ${JSON.stringify(args[1])}`);
42
+ }
43
+ return [common.encodePath(args[0]), args[1]];
44
+ }
45
+ throw Error(`validateOn.invalid_args: ${JSON.stringify(args)}`);
46
+ }
47
+ async function mapStream(stream2, fn) {
48
+ for await (const value of stream2) {
49
+ fn(value);
50
+ }
51
+ }
52
+ function shiftFn(fn, path) {
53
+ return async function shiftedFn(payload, options, next) {
54
+ let nextCalled = false;
55
+ let remainingNextResult;
56
+ const unwrappedPayload = common.unwrap(payload, path);
57
+ const remainingPayload = common.remove(payload, path) || [];
58
+ async function shiftedNext(unwrappedNextPayload) {
59
+ nextCalled = true;
60
+ const nextPayload = common.wrap(unwrappedNextPayload, path);
61
+ if (remainingPayload.length)
62
+ common.merge(nextPayload, remainingPayload);
63
+ const nextResult = await next(nextPayload);
64
+ remainingNextResult = common.remove(nextResult, path) || [];
65
+ return common.unwrap(nextResult, path);
66
+ }
67
+ const rawResult = await fn(unwrappedPayload, options, shiftedNext);
68
+ const result = common.wrap(rawResult, path);
69
+ if (!nextCalled && remainingPayload.length) {
70
+ remainingNextResult = await next(remainingPayload);
71
+ }
72
+ if (remainingNextResult && remainingNextResult.length) {
73
+ common.merge(result, remainingNextResult);
74
+ }
75
+ return result;
76
+ };
77
+ }
78
+ function shiftGen(fn, path) {
79
+ return async function* shiftedGen(payload, options, next) {
80
+ let nextCalled = false;
81
+ let remainingNextStream;
82
+ const unwrappedPayload = common.unwrap(payload, path);
83
+ const remainingPayload = common.remove(payload, path) || [];
84
+ const shiftedNext = async function* shiftedNextFn(unwrappedNextPayload) {
85
+ nextCalled = true;
86
+ const nextPayload = common.wrap(unwrappedNextPayload, path);
87
+ if (remainingPayload.length)
88
+ common.merge(nextPayload, remainingPayload);
89
+ let pushRemaining;
90
+ remainingNextStream = stream.makeStream((push) => {
91
+ pushRemaining = push;
92
+ });
93
+ for await (const value of next(nextPayload)) {
94
+ const unwrappedValue = common.unwrap(value, path);
95
+ const remainingValue = common.remove(value, path);
96
+ if (remainingValue)
97
+ pushRemaining(remainingValue);
98
+ if (unwrappedValue)
99
+ yield unwrappedValue;
100
+ }
101
+ };
102
+ const unwrappedStream = fn(unwrappedPayload, options, shiftedNext);
103
+ const firstValue = await (await unwrappedStream.next()).value;
104
+ const resultStream = stream.makeStream((push) => {
105
+ push(common.wrap(firstValue, path));
106
+ mapStream(unwrappedStream, (value) => {
107
+ push(common.wrap(value, path));
108
+ });
109
+ return () => unwrappedStream.return();
110
+ });
111
+ if (!nextCalled && remainingPayload.length) {
112
+ remainingNextStream = next(remainingPayload);
113
+ }
114
+ yield* remainingNextStream ? common.mergeStreams(resultStream, remainingNextStream) : resultStream;
115
+ };
116
+ }
117
+ const log = debug__default["default"]("graffy:core");
118
+ function resolve(handlers, firstPayload, options) {
119
+ if (!handlers || !handlers.length)
120
+ throw Error("resolve.no_provider");
121
+ function run(i, payload) {
122
+ if (i >= handlers.length) {
123
+ throw Error("resolve.no_providers_for " + JSON.stringify(payload));
124
+ }
125
+ const { path, handle } = handlers[i];
126
+ if (!common.unwrap(payload, path))
127
+ return run(i + 1, payload);
128
+ let nextCalled = false;
129
+ return handle(payload, options, (nextPayload) => {
130
+ if (nextCalled) {
131
+ throw Error("resolve.duplicate_next_call: " + handlers[i].name);
132
+ }
133
+ if (typeof nextPayload === "undefined") {
134
+ throw Error("resolve.next_without_payload: " + handlers[i].name);
135
+ }
136
+ nextCalled = true;
137
+ return run(i + 1, nextPayload);
138
+ });
139
+ }
140
+ return run(0, firstPayload);
141
+ }
142
+ class Core {
143
+ constructor() {
144
+ this.handlers = {};
145
+ }
146
+ on(type, path, handle) {
147
+ this.handlers[type] = this.handlers[type] || [];
148
+ this.handlers[type].push({ path, handle });
149
+ }
150
+ call(type, payload, options = {}) {
151
+ log("call", type, testing.format(payload));
152
+ return resolve(this.handlers[type], payload, options);
153
+ }
154
+ }
155
+ class Graffy {
156
+ constructor(path = [], core = new Core()) {
157
+ this.core = core;
158
+ this.path = path;
159
+ }
160
+ on(type, ...args) {
161
+ const [pathArg, handler] = validateOn(...args);
162
+ const path = this.path.concat(pathArg);
163
+ this.core.on(type, path, handler);
164
+ }
165
+ onRead(...args) {
166
+ const [pathArg, handle] = validateOn(...args);
167
+ const path = this.path.concat(pathArg);
168
+ this.core.on("read", path, shiftFn(async function porcelainRead(query, options) {
169
+ const decoded = common.decodeQuery(query);
170
+ const encoded = common.encodeGraph(await handle(decoded, options));
171
+ const finalized = common.finalize(encoded, query);
172
+ return finalized;
173
+ }, path));
174
+ }
175
+ onWatch(...args) {
176
+ const [pathArg, handle] = validateOn(...args);
177
+ const path = this.path.concat(pathArg);
178
+ this.core.on("watch", path, shiftGen(function porcelainWatch(query, options) {
179
+ return stream.makeStream((push, end) => {
180
+ const subscription = handle(common.decodeQuery(query), options);
181
+ (async function() {
182
+ try {
183
+ let firstValue = (await subscription.next()).value;
184
+ push(firstValue && common.finalize(common.encodeGraph(firstValue), query));
185
+ for await (const value of subscription) {
186
+ push(value && common.encodeGraph(value));
187
+ }
188
+ } catch (e) {
189
+ end(e);
190
+ }
191
+ })();
192
+ return () => subscription.return();
193
+ });
194
+ }, path));
195
+ }
196
+ onWrite(...args) {
197
+ const [pathArg, handle] = validateOn(...args);
198
+ const path = this.path.concat(pathArg);
199
+ this.core.on("write", path, shiftFn(async function porcelainWrite(change, options) {
200
+ return common.encodeGraph(await handle(common.decodeGraph(change), options));
201
+ }, path));
202
+ }
203
+ use(...args) {
204
+ const [path, provider] = validateOn(...args);
205
+ provider(new Graffy(path, this.core));
206
+ }
207
+ call(type, payload, options = {}) {
208
+ return this.core.call(type, payload, options);
209
+ }
210
+ async read(...args) {
211
+ const [path, porcelainQuery, options] = validateCall(...args);
212
+ const rootQuery = common.wrapObject(porcelainQuery, path);
213
+ const query = common.encodeQuery(rootQuery);
214
+ const result = await this.core.call("read", query, options || {});
215
+ return common.unwrapObject(common.decorate(result, rootQuery), common.decodePath(path));
216
+ }
217
+ watch(...args) {
218
+ const [path, porcelainQuery, options] = validateCall(...args);
219
+ const rootQuery = common.wrapObject(porcelainQuery, path);
220
+ const query = common.encodeQuery(rootQuery);
221
+ const stream$1 = this.core.call("watch", query, options || {});
222
+ return stream.mapStream(stream$1, (value) => common.unwrapObject(common.decorate(value, rootQuery), common.decodePath(path)));
223
+ }
224
+ async write(...args) {
225
+ const [path, porcelainChange, options] = validateCall(...args);
226
+ const change = common.wrap(common.encodeGraph(porcelainChange), path);
227
+ const writtenChange = await this.core.call("write", change, options || {});
228
+ return common.unwrapObject(common.decodeGraph(writtenChange), common.decodePath(path));
229
+ }
230
+ }
231
+ module.exports = Graffy;
package/index.mjs CHANGED
@@ -1 +1,226 @@
1
- import{encodePath as t,unwrap as r,remove as n,wrap as o,merge as a,mergeStreams as i,encodeGraph as e,decodeGraph as c,wrapObject as s,encodeQuery as l,unwrapObject as h,decorate as f,decodePath as u,decodeQuery as d,finalize as w}from"@graffy/common";import{makeStream as y,mapStream as g}from"@graffy/stream";import p from"debug";import{format as v}from"@graffy/testing";function m(t){return t&&"object"==typeof t&&!Array.isArray(t)}function _(...r){if(1===r.length)return[[],r[0],{}];if(2===r.length){if(m(r[0])){if(!m(r[1]))throw Error(`validateCall.invalid_options: ${JSON.stringify(r[1])}`);return[[],r[0],r[1]]}return[t(r[0]),r[1],{}]}if(3===r.length){if(!m(r[2]))throw Error(`validateCall.invalid_options: ${JSON.stringify(r[1])}`);return[t(r[0]),r[1],r[2]]}throw Error(`validateCall.invalid_args: ${JSON.stringify(r)}`)}function E(...r){if(1===r.length){if("function"!=typeof r[0])throw Error(`validateOn.invalid_handler: ${JSON.stringify(r[0])}`);return[[],r[0]]}if(2===r.length){if("function"!=typeof r[1])throw Error(`validateOn.invalid_handler: ${JSON.stringify(r[1])}`);return[t(r[0]),r[1]]}throw Error(`validateOn.invalid_args: ${JSON.stringify(r)}`)}function O(t,i){return async function(e,c,s){let l,h=!1;const f=r(e,i),u=n(e,i)||[];const d=await t(f,c,(async function(t){h=!0;const e=o(t,i);u.length&&a(e,u);const c=await s(e);return l=n(c,i)||[],r(c,i)})),w=o(d,i);return!h&&u.length&&(l=await s(u)),l&&l.length&&a(w,l),w}}const S=p("graffy:core");class J{constructor(){this.handlers={}}on(t,r,n){this.handlers[t]=this.handlers[t]||[],this.handlers[t].push({path:r,handle:n})}call(t,n,o={}){return S("call",t,v(n)),function(t,n,o){if(!t||!t.length)throw Error("resolve.no_provider");return function n(a,i){if(a>=t.length)throw Error("resolve.no_providers_for "+JSON.stringify(i));const{path:e,handle:c}=t[a];if(!r(i,e))return n(a+1,i);let s=!1;return c(i,o,(r=>{if(s)throw Error("resolve.duplicate_next_call: "+t[a].name);if(void 0===r)throw Error("resolve.next_without_payload: "+t[a].name);return s=!0,n(a+1,r)}))}(0,n)}(this.handlers[t],n,o)}}class N{constructor(t=[],r=new J){this.core=r,this.path=t}on(t,...r){const[n,o]=E(...r),a=this.path.concat(n);this.core.on(t,a,o)}onRead(...t){const[r,n]=E(...t),o=this.path.concat(r);this.core.on("read",o,O((async function(t,r){const o=d(t),a=e(await n(o,r));return w(a,t)}),o))}onWatch(...t){const[c,s]=E(...t),l=this.path.concat(c);this.core.on("watch",l,function(t,e){return async function*(c,s,l){let h,f=!1;const u=r(c,e),d=n(c,e)||[],w=t(u,s,(async function*(t){f=!0;const i=o(t,e);let c;d.length&&a(i,d),h=y((t=>{c=t}));for await(const o of l(i)){const t=r(o,e),a=n(o,e);a&&c(a),t&&(yield t)}})),g=await(await w.next()).value,p=y((t=>(t(o(g,e)),async function(t,r){for await(const n of t)r(n)}(w,(r=>{t(o(r,e))})),()=>w.return())));!f&&d.length&&(h=l(d)),yield*h?i(p,h):p}}((function(t,r){return y(((n,o)=>{const a=s(d(t),r);return async function(){try{let r=(await a.next()).value;n(r&&w(e(r),t));for await(const t of a)n(t&&e(t))}catch(r){o(r)}}(),()=>a.return()}))}),l))}onWrite(...t){const[r,n]=E(...t),o=this.path.concat(r);this.core.on("write",o,O((async function(t,r){return e(await n(c(t),r))}),o))}use(...t){const[r,n]=E(...t);n(new N(r,this.core))}call(t,r,n={}){return this.core.call(t,r,n)}async read(...t){const[r,n,o]=_(...t),a=s(n,r),i=l(a),e=await this.core.call("read",i,o||{});return h(f(e,a),u(r))}watch(...t){const[r,n,o]=_(...t),a=s(n,r),i=l(a),e=this.core.call("watch",i,o||{});return g(e,(t=>h(f(t,a),u(r))))}async write(...t){const[r,n,a]=_(...t),i=o(e(n),r),s=await this.core.call("write",i,a||{});return h(c(s),u(r))}}export{N as default};
1
+ import { encodePath, unwrap, remove, wrap, merge, mergeStreams, encodeGraph, decodeGraph, wrapObject, encodeQuery, unwrapObject, decorate, decodePath, decodeQuery, finalize } from "@graffy/common";
2
+ import { makeStream, mapStream as mapStream$1 } from "@graffy/stream";
3
+ import debug from "debug";
4
+ import { format } from "@graffy/testing";
5
+ function isPlainObject(obj) {
6
+ return obj && typeof obj === "object" && !Array.isArray(obj);
7
+ }
8
+ function validateCall(...args) {
9
+ if (args.length === 1) {
10
+ return [[], args[0], {}];
11
+ } else if (args.length === 2) {
12
+ if (isPlainObject(args[0])) {
13
+ if (!isPlainObject(args[1])) {
14
+ throw Error(`validateCall.invalid_options: ${JSON.stringify(args[1])}`);
15
+ }
16
+ return [[], args[0], args[1]];
17
+ } else {
18
+ return [encodePath(args[0]), args[1], {}];
19
+ }
20
+ } else if (args.length === 3) {
21
+ if (!isPlainObject(args[2])) {
22
+ throw Error(`validateCall.invalid_options: ${JSON.stringify(args[1])}`);
23
+ }
24
+ return [encodePath(args[0]), args[1], args[2]];
25
+ }
26
+ throw Error(`validateCall.invalid_args: ${JSON.stringify(args)}`);
27
+ }
28
+ function validateOn(...args) {
29
+ if (args.length === 1) {
30
+ if (typeof args[0] !== "function") {
31
+ throw Error(`validateOn.invalid_handler: ${JSON.stringify(args[0])}`);
32
+ }
33
+ return [[], args[0]];
34
+ } else if (args.length === 2) {
35
+ if (typeof args[1] !== "function") {
36
+ throw Error(`validateOn.invalid_handler: ${JSON.stringify(args[1])}`);
37
+ }
38
+ return [encodePath(args[0]), args[1]];
39
+ }
40
+ throw Error(`validateOn.invalid_args: ${JSON.stringify(args)}`);
41
+ }
42
+ async function mapStream(stream, fn) {
43
+ for await (const value of stream) {
44
+ fn(value);
45
+ }
46
+ }
47
+ function shiftFn(fn, path) {
48
+ return async function shiftedFn(payload, options, next) {
49
+ let nextCalled = false;
50
+ let remainingNextResult;
51
+ const unwrappedPayload = unwrap(payload, path);
52
+ const remainingPayload = remove(payload, path) || [];
53
+ async function shiftedNext(unwrappedNextPayload) {
54
+ nextCalled = true;
55
+ const nextPayload = wrap(unwrappedNextPayload, path);
56
+ if (remainingPayload.length)
57
+ merge(nextPayload, remainingPayload);
58
+ const nextResult = await next(nextPayload);
59
+ remainingNextResult = remove(nextResult, path) || [];
60
+ return unwrap(nextResult, path);
61
+ }
62
+ const rawResult = await fn(unwrappedPayload, options, shiftedNext);
63
+ const result = wrap(rawResult, path);
64
+ if (!nextCalled && remainingPayload.length) {
65
+ remainingNextResult = await next(remainingPayload);
66
+ }
67
+ if (remainingNextResult && remainingNextResult.length) {
68
+ merge(result, remainingNextResult);
69
+ }
70
+ return result;
71
+ };
72
+ }
73
+ function shiftGen(fn, path) {
74
+ return async function* shiftedGen(payload, options, next) {
75
+ let nextCalled = false;
76
+ let remainingNextStream;
77
+ const unwrappedPayload = unwrap(payload, path);
78
+ const remainingPayload = remove(payload, path) || [];
79
+ const shiftedNext = async function* shiftedNextFn(unwrappedNextPayload) {
80
+ nextCalled = true;
81
+ const nextPayload = wrap(unwrappedNextPayload, path);
82
+ if (remainingPayload.length)
83
+ merge(nextPayload, remainingPayload);
84
+ let pushRemaining;
85
+ remainingNextStream = makeStream((push) => {
86
+ pushRemaining = push;
87
+ });
88
+ for await (const value of next(nextPayload)) {
89
+ const unwrappedValue = unwrap(value, path);
90
+ const remainingValue = remove(value, path);
91
+ if (remainingValue)
92
+ pushRemaining(remainingValue);
93
+ if (unwrappedValue)
94
+ yield unwrappedValue;
95
+ }
96
+ };
97
+ const unwrappedStream = fn(unwrappedPayload, options, shiftedNext);
98
+ const firstValue = await (await unwrappedStream.next()).value;
99
+ const resultStream = makeStream((push) => {
100
+ push(wrap(firstValue, path));
101
+ mapStream(unwrappedStream, (value) => {
102
+ push(wrap(value, path));
103
+ });
104
+ return () => unwrappedStream.return();
105
+ });
106
+ if (!nextCalled && remainingPayload.length) {
107
+ remainingNextStream = next(remainingPayload);
108
+ }
109
+ yield* remainingNextStream ? mergeStreams(resultStream, remainingNextStream) : resultStream;
110
+ };
111
+ }
112
+ const log = debug("graffy:core");
113
+ function resolve(handlers, firstPayload, options) {
114
+ if (!handlers || !handlers.length)
115
+ throw Error("resolve.no_provider");
116
+ function run(i, payload) {
117
+ if (i >= handlers.length) {
118
+ throw Error("resolve.no_providers_for " + JSON.stringify(payload));
119
+ }
120
+ const { path, handle } = handlers[i];
121
+ if (!unwrap(payload, path))
122
+ return run(i + 1, payload);
123
+ let nextCalled = false;
124
+ return handle(payload, options, (nextPayload) => {
125
+ if (nextCalled) {
126
+ throw Error("resolve.duplicate_next_call: " + handlers[i].name);
127
+ }
128
+ if (typeof nextPayload === "undefined") {
129
+ throw Error("resolve.next_without_payload: " + handlers[i].name);
130
+ }
131
+ nextCalled = true;
132
+ return run(i + 1, nextPayload);
133
+ });
134
+ }
135
+ return run(0, firstPayload);
136
+ }
137
+ class Core {
138
+ constructor() {
139
+ this.handlers = {};
140
+ }
141
+ on(type, path, handle) {
142
+ this.handlers[type] = this.handlers[type] || [];
143
+ this.handlers[type].push({ path, handle });
144
+ }
145
+ call(type, payload, options = {}) {
146
+ log("call", type, format(payload));
147
+ return resolve(this.handlers[type], payload, options);
148
+ }
149
+ }
150
+ class Graffy {
151
+ constructor(path = [], core = new Core()) {
152
+ this.core = core;
153
+ this.path = path;
154
+ }
155
+ on(type, ...args) {
156
+ const [pathArg, handler] = validateOn(...args);
157
+ const path = this.path.concat(pathArg);
158
+ this.core.on(type, path, handler);
159
+ }
160
+ onRead(...args) {
161
+ const [pathArg, handle] = validateOn(...args);
162
+ const path = this.path.concat(pathArg);
163
+ this.core.on("read", path, shiftFn(async function porcelainRead(query, options) {
164
+ const decoded = decodeQuery(query);
165
+ const encoded = encodeGraph(await handle(decoded, options));
166
+ const finalized = finalize(encoded, query);
167
+ return finalized;
168
+ }, path));
169
+ }
170
+ onWatch(...args) {
171
+ const [pathArg, handle] = validateOn(...args);
172
+ const path = this.path.concat(pathArg);
173
+ this.core.on("watch", path, shiftGen(function porcelainWatch(query, options) {
174
+ return makeStream((push, end) => {
175
+ const subscription = handle(decodeQuery(query), options);
176
+ (async function() {
177
+ try {
178
+ let firstValue = (await subscription.next()).value;
179
+ push(firstValue && finalize(encodeGraph(firstValue), query));
180
+ for await (const value of subscription) {
181
+ push(value && encodeGraph(value));
182
+ }
183
+ } catch (e) {
184
+ end(e);
185
+ }
186
+ })();
187
+ return () => subscription.return();
188
+ });
189
+ }, path));
190
+ }
191
+ onWrite(...args) {
192
+ const [pathArg, handle] = validateOn(...args);
193
+ const path = this.path.concat(pathArg);
194
+ this.core.on("write", path, shiftFn(async function porcelainWrite(change, options) {
195
+ return encodeGraph(await handle(decodeGraph(change), options));
196
+ }, path));
197
+ }
198
+ use(...args) {
199
+ const [path, provider] = validateOn(...args);
200
+ provider(new Graffy(path, this.core));
201
+ }
202
+ call(type, payload, options = {}) {
203
+ return this.core.call(type, payload, options);
204
+ }
205
+ async read(...args) {
206
+ const [path, porcelainQuery, options] = validateCall(...args);
207
+ const rootQuery = wrapObject(porcelainQuery, path);
208
+ const query = encodeQuery(rootQuery);
209
+ const result = await this.core.call("read", query, options || {});
210
+ return unwrapObject(decorate(result, rootQuery), decodePath(path));
211
+ }
212
+ watch(...args) {
213
+ const [path, porcelainQuery, options] = validateCall(...args);
214
+ const rootQuery = wrapObject(porcelainQuery, path);
215
+ const query = encodeQuery(rootQuery);
216
+ const stream = this.core.call("watch", query, options || {});
217
+ return mapStream$1(stream, (value) => unwrapObject(decorate(value, rootQuery), decodePath(path)));
218
+ }
219
+ async write(...args) {
220
+ const [path, porcelainChange, options] = validateCall(...args);
221
+ const change = wrap(encodeGraph(porcelainChange), path);
222
+ const writtenChange = await this.core.call("write", change, options || {});
223
+ return unwrapObject(decodeGraph(writtenChange), decodePath(path));
224
+ }
225
+ }
226
+ export { Graffy as default };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graffy/core",
3
3
  "description": "The main module for Graffy, a library for intuitive real-time data APIs.",
4
4
  "author": "aravind (https://github.com/aravindet)",
5
- "version": "0.15.8-alpha.5",
5
+ "version": "0.15.8",
6
6
  "main": "./index.cjs",
7
7
  "exports": {
8
8
  "import": "./index.mjs",
@@ -16,9 +16,9 @@
16
16
  },
17
17
  "license": "Apache-2.0",
18
18
  "dependencies": {
19
- "@graffy/common": "0.15.8-alpha.5",
20
- "@graffy/stream": "0.15.8-alpha.5",
19
+ "@graffy/common": "0.15.8",
20
+ "@graffy/stream": "0.15.8",
21
21
  "debug": "^4.3.2",
22
- "@graffy/testing": "0.15.8-alpha.5"
22
+ "@graffy/testing": "0.15.8"
23
23
  }
24
24
  }