@luvio/lwc-luvio 0.138.1 → 0.138.2

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 (40) hide show
  1. package/dist/es/es2018/lwcluvio.js +521 -521
  2. package/dist/es/es2018/{LWCGraphQLLuvioWireAdapter.d.ts → types/LWCGraphQLLuvioWireAdapter.d.ts} +56 -56
  3. package/dist/{umd/es2018 → es/es2018/types}/LWCInfiniteScrollingLuvioWireAdapter.d.ts +26 -26
  4. package/dist/{umd/es2018 → es/es2018/types}/LWCLuvioBindings.d.ts +4 -4
  5. package/dist/{umd/es5 → es/es2018/types}/LWCLuvioWireAdapter.d.ts +64 -64
  6. package/dist/es/es2018/{main.d.ts → types/main.d.ts} +8 -8
  7. package/dist/es/es2018/{utils → types/utils}/SnapshotState.d.ts +12 -12
  8. package/dist/es/es2018/{utils → types/utils}/constants.d.ts +5 -5
  9. package/dist/es/es2018/{utils → types/utils}/dataToTupleWeakMap.d.ts +2 -2
  10. package/dist/es/es2018/{utils → types/utils}/isPromise.d.ts +1 -1
  11. package/dist/es/es2018/{utils → types/utils}/language.d.ts +14 -14
  12. package/dist/{umd/es2018 → es/es2018/types}/utils/sanitize.d.ts +9 -9
  13. package/dist/{umd/es5 → es/es2018/types}/utils/throwAnnotatedError.d.ts +7 -7
  14. package/dist/umd/es2018/lwcluvio.js +521 -521
  15. package/dist/umd/{es5 → es2018/types}/LWCGraphQLLuvioWireAdapter.d.ts +56 -56
  16. package/dist/{es/es2018 → umd/es2018/types}/LWCInfiniteScrollingLuvioWireAdapter.d.ts +26 -26
  17. package/dist/umd/{es5 → es2018/types}/LWCLuvioBindings.d.ts +4 -4
  18. package/dist/umd/es2018/{LWCLuvioWireAdapter.d.ts → types/LWCLuvioWireAdapter.d.ts} +64 -64
  19. package/dist/umd/es2018/{main.d.ts → types/main.d.ts} +8 -8
  20. package/dist/umd/{es5 → es2018/types}/utils/SnapshotState.d.ts +12 -12
  21. package/dist/umd/es2018/{utils → types/utils}/constants.d.ts +5 -5
  22. package/dist/umd/es2018/{utils → types/utils}/dataToTupleWeakMap.d.ts +2 -2
  23. package/dist/umd/es2018/{utils → types/utils}/isPromise.d.ts +1 -1
  24. package/dist/umd/es2018/{utils → types/utils}/language.d.ts +14 -14
  25. package/dist/{es/es2018 → umd/es2018/types}/utils/sanitize.d.ts +9 -9
  26. package/dist/{es/es2018 → umd/es2018/types}/utils/throwAnnotatedError.d.ts +7 -7
  27. package/dist/umd/es5/lwcluvio.js +541 -541
  28. package/dist/umd/{es2018 → es5/types}/LWCGraphQLLuvioWireAdapter.d.ts +56 -56
  29. package/dist/umd/es5/{LWCInfiniteScrollingLuvioWireAdapter.d.ts → types/LWCInfiniteScrollingLuvioWireAdapter.d.ts} +26 -26
  30. package/dist/{es/es2018 → umd/es5/types}/LWCLuvioBindings.d.ts +4 -4
  31. package/dist/{es/es2018 → umd/es5/types}/LWCLuvioWireAdapter.d.ts +64 -64
  32. package/dist/umd/es5/{main.d.ts → types/main.d.ts} +8 -8
  33. package/dist/umd/{es2018 → es5/types}/utils/SnapshotState.d.ts +12 -12
  34. package/dist/umd/es5/{utils → types/utils}/constants.d.ts +5 -5
  35. package/dist/umd/es5/{utils → types/utils}/dataToTupleWeakMap.d.ts +2 -2
  36. package/dist/umd/es5/{utils → types/utils}/isPromise.d.ts +1 -1
  37. package/dist/umd/es5/{utils → types/utils}/language.d.ts +14 -14
  38. package/dist/umd/es5/{utils → types/utils}/sanitize.d.ts +9 -9
  39. package/dist/umd/{es2018 → es5/types}/utils/throwAnnotatedError.d.ts +7 -7
  40. package/package.json +7 -7
@@ -1,546 +1,546 @@
1
1
  import { unwrap } from 'lwc';
2
2
 
3
- // instrumentation keys to be imported by ldsInstrumentation
4
- const REFRESH_ADAPTER_EVENT = 'refresh-adapter-event';
5
- const ADAPTER_UNFULFILLED_ERROR = 'adapter-unfulfilled-error';
6
- const USERLAND_PROVISION_ERROR_MESSAGE = "LWC component's @wire target property or method threw an error during value provisioning. Original error:";
7
- const ADAPTER_SNAPSHOT_REJECTED_MESSAGE = 'Luvio wire adapter Promise<Snapshot> rejected. Original error:';
3
+ // instrumentation keys to be imported by ldsInstrumentation
4
+ const REFRESH_ADAPTER_EVENT = 'refresh-adapter-event';
5
+ const ADAPTER_UNFULFILLED_ERROR = 'adapter-unfulfilled-error';
6
+ const USERLAND_PROVISION_ERROR_MESSAGE = "LWC component's @wire target property or method threw an error during value provisioning. Original error:";
7
+ const ADAPTER_SNAPSHOT_REJECTED_MESSAGE = 'Luvio wire adapter Promise<Snapshot> rejected. Original error:';
8
8
  const USERLAND_GRAPHQL_PARSER_ERROR_MESSAGE = 'Use `gql` parser to parse your "query" string';
9
9
 
10
- // map of emitted object -> [ adapter name, snapshot ]; snapshot is only undefined for the
11
- // initially-emitted { data: undefined, error: undefined } value
10
+ // map of emitted object -> [ adapter name, snapshot ]; snapshot is only undefined for the
11
+ // initially-emitted { data: undefined, error: undefined } value
12
12
  const dataToTupleWeakMap = new WeakMap();
13
13
 
14
- var SnapshotState;
15
- (function (SnapshotState) {
16
- SnapshotState["Fulfilled"] = "Fulfilled";
17
- SnapshotState["Unfulfilled"] = "Unfulfilled";
18
- SnapshotState["Error"] = "Error";
19
- SnapshotState["Pending"] = "Pending";
20
- SnapshotState["Stale"] = "Stale";
21
- })(SnapshotState || (SnapshotState = {}));
22
- function isErrorSnapshot(snapshot) {
23
- return snapshot.state === SnapshotState.Error;
24
- }
25
- function isFulfilledSnapshot(snapshot) {
26
- return snapshot.state === SnapshotState.Fulfilled;
27
- }
28
- function isStaleSnapshot(snapshot) {
29
- return snapshot.state === SnapshotState.Stale;
30
- }
31
- function isUnfulfilledSnapshot(snapshot) {
32
- return snapshot.state === SnapshotState.Unfulfilled;
33
- }
34
- /**
35
- * Transform a Snapshot into a payload suitable for passing to a DataCallback.
36
- *
37
- * @param snapshot Snapshot
38
- */
39
- function snapshotToPayload$1(snapshot) {
40
- if (snapshot === undefined) {
41
- return {
42
- data: undefined,
43
- error: undefined,
44
- };
45
- }
46
- if (isErrorSnapshot(snapshot)) {
47
- return {
48
- data: undefined,
49
- error: snapshot.error,
50
- };
51
- }
52
- // fulfilled or stale
53
- return {
54
- data: snapshot.data,
55
- error: undefined,
56
- };
14
+ var SnapshotState;
15
+ (function (SnapshotState) {
16
+ SnapshotState["Fulfilled"] = "Fulfilled";
17
+ SnapshotState["Unfulfilled"] = "Unfulfilled";
18
+ SnapshotState["Error"] = "Error";
19
+ SnapshotState["Pending"] = "Pending";
20
+ SnapshotState["Stale"] = "Stale";
21
+ })(SnapshotState || (SnapshotState = {}));
22
+ function isErrorSnapshot(snapshot) {
23
+ return snapshot.state === SnapshotState.Error;
24
+ }
25
+ function isFulfilledSnapshot(snapshot) {
26
+ return snapshot.state === SnapshotState.Fulfilled;
27
+ }
28
+ function isStaleSnapshot(snapshot) {
29
+ return snapshot.state === SnapshotState.Stale;
30
+ }
31
+ function isUnfulfilledSnapshot(snapshot) {
32
+ return snapshot.state === SnapshotState.Unfulfilled;
33
+ }
34
+ /**
35
+ * Transform a Snapshot into a payload suitable for passing to a DataCallback.
36
+ *
37
+ * @param snapshot Snapshot
38
+ */
39
+ function snapshotToPayload$1(snapshot) {
40
+ if (snapshot === undefined) {
41
+ return {
42
+ data: undefined,
43
+ error: undefined,
44
+ };
45
+ }
46
+ if (isErrorSnapshot(snapshot)) {
47
+ return {
48
+ data: undefined,
49
+ error: snapshot.error,
50
+ };
51
+ }
52
+ // fulfilled or stale
53
+ return {
54
+ data: snapshot.data,
55
+ error: undefined,
56
+ };
57
57
  }
58
58
 
59
- function bindWireRefresh(luvio) {
60
- return function refresh(data) {
61
- return refreshData(data, dataToTupleWeakMap, luvio);
62
- };
63
- }
64
- function refreshData(data, dataToTuple, luvio) {
65
- const tuple = dataToTuple.get(unwrap(data));
66
- if (tuple === undefined) {
67
- if (process.env.NODE_ENV !== 'production') {
68
- throw new Error('Refresh failed because resolved configuration is not available.');
69
- }
70
- return;
71
- }
72
- const [adapterName, snapshot] = tuple;
73
- luvio.instrument(() => {
74
- return {
75
- [REFRESH_ADAPTER_EVENT]: true,
76
- adapterName,
77
- };
78
- });
79
- // snapshot is undefined when a caller refreshes the initial
80
- // { data: undefined, error: undefined } object that we emitted
81
- if (snapshot === undefined) {
82
- return Promise.resolve(undefined);
83
- }
84
- return luvio.refreshSnapshot(snapshot).then((refreshed) => {
85
- if (isErrorSnapshot(refreshed)) {
86
- throw refreshed.error;
87
- }
88
- if (process.env.NODE_ENV !== 'production') {
89
- if (isUnfulfilledSnapshot(refreshed)) {
90
- throw new Error('Refresh resulted in unfulfilled snapshot');
91
- }
92
- }
93
- return undefined;
94
- });
59
+ function bindWireRefresh(luvio) {
60
+ return function refresh(data) {
61
+ return refreshData(data, dataToTupleWeakMap, luvio);
62
+ };
63
+ }
64
+ function refreshData(data, dataToTuple, luvio) {
65
+ const tuple = dataToTuple.get(unwrap(data));
66
+ if (tuple === undefined) {
67
+ if (process.env.NODE_ENV !== 'production') {
68
+ throw new Error('Refresh failed because resolved configuration is not available.');
69
+ }
70
+ return;
71
+ }
72
+ const [adapterName, snapshot] = tuple;
73
+ luvio.instrument(() => {
74
+ return {
75
+ [REFRESH_ADAPTER_EVENT]: true,
76
+ adapterName,
77
+ };
78
+ });
79
+ // snapshot is undefined when a caller refreshes the initial
80
+ // { data: undefined, error: undefined } object that we emitted
81
+ if (snapshot === undefined) {
82
+ return Promise.resolve(undefined);
83
+ }
84
+ return luvio.refreshSnapshot(snapshot).then((refreshed) => {
85
+ if (isErrorSnapshot(refreshed)) {
86
+ throw refreshed.error;
87
+ }
88
+ if (process.env.NODE_ENV !== 'production') {
89
+ if (isUnfulfilledSnapshot(refreshed)) {
90
+ throw new Error('Refresh resulted in unfulfilled snapshot');
91
+ }
92
+ }
93
+ return undefined;
94
+ });
95
95
  }
96
96
 
97
- const { freeze, keys } = Object;
98
- const { isArray } = Array;
97
+ const { freeze, keys } = Object;
98
+ const { isArray } = Array;
99
99
  const { stringify } = JSON;
100
100
 
101
- function isPromise(value) {
102
- // check for Thenable due to test frameworks using custom Promise impls
103
- return value.then !== undefined;
101
+ function isPromise(value) {
102
+ // check for Thenable due to test frameworks using custom Promise impls
103
+ return value.then !== undefined;
104
104
  }
105
105
 
106
- /**
107
- * (Re)throws an error after adding a prefix to the message.
108
- *
109
- * @param error Error
110
- * @param messagePrefix prefix to add to error's message
111
- */
112
- function throwAnnotatedError(error, messagePrefix) {
113
- if (error instanceof Error) {
114
- error.message = `${messagePrefix}\n[${error.message}]`;
115
- throw error;
116
- }
117
- throw new Error(`${messagePrefix}\n[${stringify(error)}]`);
106
+ /**
107
+ * (Re)throws an error after adding a prefix to the message.
108
+ *
109
+ * @param error Error
110
+ * @param messagePrefix prefix to add to error's message
111
+ */
112
+ function throwAnnotatedError(error, messagePrefix) {
113
+ if (error instanceof Error) {
114
+ error.message = `${messagePrefix}\n[${error.message}]`;
115
+ throw error;
116
+ }
117
+ throw new Error(`${messagePrefix}\n[${stringify(error)}]`);
118
118
  }
119
119
 
120
- class Sanitizer {
121
- constructor(obj) {
122
- this.obj = obj;
123
- this.copy = {};
124
- this.currentPath = {
125
- key: '',
126
- value: obj,
127
- parent: null,
128
- data: this.copy,
129
- };
130
- }
131
- sanitize() {
132
- const sanitizer = this;
133
- stringify(this.obj, function (key, value) {
134
- if (key === '') {
135
- return value;
136
- }
137
- const parent = this;
138
- if (parent !== sanitizer.currentPath.value) {
139
- sanitizer.exit(parent);
140
- }
141
- if (typeof value === 'object' && value !== null) {
142
- sanitizer.enter(key, value);
143
- return value;
144
- }
145
- sanitizer.currentPath.data[key] = value;
146
- return value;
147
- });
148
- return this.copy;
149
- }
150
- enter(key, value) {
151
- const { currentPath: parentPath } = this;
152
- const data = (parentPath.data[key] = isArray(value) ? [] : {});
153
- this.currentPath = {
154
- key,
155
- value,
156
- parent: parentPath,
157
- data,
158
- };
159
- }
160
- exit(parent) {
161
- while (this.currentPath.value !== parent) {
162
- this.currentPath = this.currentPath.parent || this.currentPath;
163
- }
164
- }
165
- }
166
- /**
167
- * Returns a sanitized version of an object by recursively unwrapping the Proxies.
168
- *
169
- * In order to keep luvio performance optimal on IE11, we need to make sure that luvio code gets
170
- * transformed by the es5-proxy-compat. At the same time we need to ensure that no ProxyCompat leaks
171
- * into the luvio engine code nor into the adapters. All the data coming from LWC-land need to be
172
- * sanitized first.
173
- */
174
- function sanitize(obj) {
175
- return new Sanitizer(obj).sanitize();
120
+ class Sanitizer {
121
+ constructor(obj) {
122
+ this.obj = obj;
123
+ this.copy = {};
124
+ this.currentPath = {
125
+ key: '',
126
+ value: obj,
127
+ parent: null,
128
+ data: this.copy,
129
+ };
130
+ }
131
+ sanitize() {
132
+ const sanitizer = this;
133
+ stringify(this.obj, function (key, value) {
134
+ if (key === '') {
135
+ return value;
136
+ }
137
+ const parent = this;
138
+ if (parent !== sanitizer.currentPath.value) {
139
+ sanitizer.exit(parent);
140
+ }
141
+ if (typeof value === 'object' && value !== null) {
142
+ sanitizer.enter(key, value);
143
+ return value;
144
+ }
145
+ sanitizer.currentPath.data[key] = value;
146
+ return value;
147
+ });
148
+ return this.copy;
149
+ }
150
+ enter(key, value) {
151
+ const { currentPath: parentPath } = this;
152
+ const data = (parentPath.data[key] = isArray(value) ? [] : {});
153
+ this.currentPath = {
154
+ key,
155
+ value,
156
+ parent: parentPath,
157
+ data,
158
+ };
159
+ }
160
+ exit(parent) {
161
+ while (this.currentPath.value !== parent) {
162
+ this.currentPath = this.currentPath.parent || this.currentPath;
163
+ }
164
+ }
165
+ }
166
+ /**
167
+ * Returns a sanitized version of an object by recursively unwrapping the Proxies.
168
+ *
169
+ * In order to keep luvio performance optimal on IE11, we need to make sure that luvio code gets
170
+ * transformed by the es5-proxy-compat. At the same time we need to ensure that no ProxyCompat leaks
171
+ * into the luvio engine code nor into the adapters. All the data coming from LWC-land need to be
172
+ * sanitized first.
173
+ */
174
+ function sanitize(obj) {
175
+ return new Sanitizer(obj).sanitize();
176
176
  }
177
177
 
178
- class LWCLuvioWireAdapter {
179
- /**
180
- * Constructs a new wire adapter instance for the given adapter.
181
- *
182
- * @param callback callback to be invoked with new values
183
- */
184
- constructor(adapter, name, luvio, callback) {
185
- // a component can be connected-disconnected-reconnected multiple times during its
186
- // life but we only want to keep subscriptions active while it is connected; the
187
- // connect/disconnect methods below keep this value updated to reflect the current
188
- // state
189
- this.connected = false;
190
- this.adapter = adapter;
191
- this.name = name;
192
- this.luvio = luvio;
193
- this.callback = callback;
194
- // initialize the wired property with a properly shaped object so cmps can use <template if:true={wiredProperty.data}>
195
- this.emit();
196
- }
197
- // WireAdapter interface methods
198
- /**
199
- * Called when the component associated with the wire adapter is connected.
200
- */
201
- connect() {
202
- this.connected = true;
203
- this.callAdapter();
204
- }
205
- /**
206
- * Called when the component associated with the wire adapter is disconnected.
207
- */
208
- disconnect() {
209
- this.unsubscribe();
210
- this.connected = false;
211
- }
212
- /**
213
- * Called when new or updated config is supplied to the wire adapter.
214
- *
215
- * @param config new config parameters for the wire adapter
216
- * @param _context not used
217
- */
218
- update(config, _context) {
219
- this.unsubscribe();
220
- this.config = sanitize(config);
221
- this.callAdapter();
222
- }
223
- // private and protected utility methods
224
- /**
225
- * Calls the adapter if config has been set and the component is connected.
226
- */
227
- callAdapter() {
228
- if (!this.connected || this.config === undefined) {
229
- return;
230
- }
231
- const snapshotOrPromise = this.adapter(this.config);
232
- this.processAdapterResponse(snapshotOrPromise);
233
- }
234
- processAdapterResponse(snapshotOrPromise) {
235
- // insufficient config, wait for new config from component
236
- if (snapshotOrPromise === null) {
237
- return;
238
- }
239
- const configForSnapshot = this.config;
240
- const emitAndSubscribe = (snapshot) => {
241
- // adapters leveraging adapter context could asynchronously
242
- // return null (due to invalid config)
243
- if (snapshot === null) {
244
- return;
245
- }
246
- // We should never broadcast an unfulfilled snapshot to a component
247
- if (isUnfulfilledSnapshot(snapshot)) {
248
- if (process.env.NODE_ENV !== 'production') {
249
- throw new Error(`Unfulfilled snapshot emitted to component from subscription, missingPaths: ${keys(snapshot.missingPaths)}`);
250
- }
251
- // Instrument as a failed request
252
- this.luvio.instrument(() => {
253
- return {
254
- [ADAPTER_UNFULFILLED_ERROR]: true,
255
- adapterName: this.adapter.name,
256
- missingPaths: snapshot.missingPaths,
257
- missingLinks: snapshot.missingLinks,
258
- };
259
- });
260
- return;
261
- }
262
- // if config has changed before the snapshot arrives then ignore snapshot
263
- if (this.config !== configForSnapshot) {
264
- return;
265
- }
266
- // emit unless snapshot is pending
267
- if (isFulfilledSnapshot(snapshot) ||
268
- isErrorSnapshot(snapshot) ||
269
- isStaleSnapshot(snapshot)) {
270
- this.emit(snapshot);
271
- }
272
- // subscribe to the new snapshot
273
- this.subscribe(snapshot);
274
- };
275
- // Data resolved sync
276
- if (!isPromise(snapshotOrPromise)) {
277
- emitAndSubscribe(snapshotOrPromise);
278
- }
279
- else {
280
- // We want to let errors from this promise propagate to the app container,
281
- // which is why we do not have a reject handler here.
282
- // If an error is thrown here, it means that there was an error somewhere
283
- // inside an adapter which means that there was a mistake by the implementor.
284
- // Errors that come from the network should never hit this block because
285
- // they are treated like regular snapshots, not true error paths.
286
- snapshotOrPromise.then(emitAndSubscribe, (error) => throwAnnotatedError(error, ADAPTER_SNAPSHOT_REJECTED_MESSAGE));
287
- }
288
- }
289
- /**
290
- * Emits new values to the callback.
291
- *
292
- * @param snapshot Snapshot to be emitted, if omitted then undefineds will be emitted
293
- */
294
- emit(snapshot) {
295
- const payload = snapshotToPayload$1(snapshot);
296
- dataToTupleWeakMap.set(payload, [this.name, snapshot]);
297
- try {
298
- this.callback(payload);
299
- }
300
- catch (error) {
301
- if (error instanceof Error) {
302
- throwAnnotatedError(error, USERLAND_PROVISION_ERROR_MESSAGE);
303
- }
304
- }
305
- }
306
- /**
307
- * Subscribes this wire adapter to future changes to the specified snapshot. Any changes
308
- * to the snapshot will be automatically emitted to the component.
309
- *
310
- * @param snapshot Snapshot
311
- * @param subscriptionCallback callback
312
- */
313
- subscribe(snapshot) {
314
- // always clean up any old subscription that we might have
315
- this.unsubscribe();
316
- // but only subscribe if component is currently connected
317
- if (this.connected) {
318
- this.unsubscriber = this.luvio.storeSubscribe(snapshot, this.emit.bind(this));
319
- }
320
- }
321
- /**
322
- * Deletes this wire adapter's snapshot subscription (if any).
323
- */
324
- unsubscribe() {
325
- // clean up subscription
326
- if (this.unsubscriber !== undefined) {
327
- this.unsubscriber();
328
- this.unsubscriber = undefined;
329
- }
330
- }
331
- }
332
- /**
333
- * Wraps a luvio Adapter in a WireAdapterConstructor that conforms to https://rfcs.lwc.dev/rfcs/lwc/0000-wire-reform#wire-adapter-protocol.
334
- *
335
- * @param adapter Adapter
336
- * @param name name to assign to the generated constructor
337
- * @param luvio Luvio
338
- */
339
- function createWireAdapterConstructor(adapter, name, luvio) {
340
- const constructor = function (callback) {
341
- const delegate = new LWCLuvioWireAdapter(adapter, name, luvio, callback);
342
- this.connect = () => delegate.connect();
343
- this.disconnect = () => delegate.disconnect();
344
- this.update = (config, context) => delegate.update(config, context);
345
- };
346
- Object.defineProperty(constructor, 'name', { value: name });
347
- return constructor;
178
+ class LWCLuvioWireAdapter {
179
+ /**
180
+ * Constructs a new wire adapter instance for the given adapter.
181
+ *
182
+ * @param callback callback to be invoked with new values
183
+ */
184
+ constructor(adapter, name, luvio, callback) {
185
+ // a component can be connected-disconnected-reconnected multiple times during its
186
+ // life but we only want to keep subscriptions active while it is connected; the
187
+ // connect/disconnect methods below keep this value updated to reflect the current
188
+ // state
189
+ this.connected = false;
190
+ this.adapter = adapter;
191
+ this.name = name;
192
+ this.luvio = luvio;
193
+ this.callback = callback;
194
+ // initialize the wired property with a properly shaped object so cmps can use <template if:true={wiredProperty.data}>
195
+ this.emit();
196
+ }
197
+ // WireAdapter interface methods
198
+ /**
199
+ * Called when the component associated with the wire adapter is connected.
200
+ */
201
+ connect() {
202
+ this.connected = true;
203
+ this.callAdapter();
204
+ }
205
+ /**
206
+ * Called when the component associated with the wire adapter is disconnected.
207
+ */
208
+ disconnect() {
209
+ this.unsubscribe();
210
+ this.connected = false;
211
+ }
212
+ /**
213
+ * Called when new or updated config is supplied to the wire adapter.
214
+ *
215
+ * @param config new config parameters for the wire adapter
216
+ * @param _context not used
217
+ */
218
+ update(config, _context) {
219
+ this.unsubscribe();
220
+ this.config = sanitize(config);
221
+ this.callAdapter();
222
+ }
223
+ // private and protected utility methods
224
+ /**
225
+ * Calls the adapter if config has been set and the component is connected.
226
+ */
227
+ callAdapter() {
228
+ if (!this.connected || this.config === undefined) {
229
+ return;
230
+ }
231
+ const snapshotOrPromise = this.adapter(this.config);
232
+ this.processAdapterResponse(snapshotOrPromise);
233
+ }
234
+ processAdapterResponse(snapshotOrPromise) {
235
+ // insufficient config, wait for new config from component
236
+ if (snapshotOrPromise === null) {
237
+ return;
238
+ }
239
+ const configForSnapshot = this.config;
240
+ const emitAndSubscribe = (snapshot) => {
241
+ // adapters leveraging adapter context could asynchronously
242
+ // return null (due to invalid config)
243
+ if (snapshot === null) {
244
+ return;
245
+ }
246
+ // We should never broadcast an unfulfilled snapshot to a component
247
+ if (isUnfulfilledSnapshot(snapshot)) {
248
+ if (process.env.NODE_ENV !== 'production') {
249
+ throw new Error(`Unfulfilled snapshot emitted to component from subscription, missingPaths: ${keys(snapshot.missingPaths)}`);
250
+ }
251
+ // Instrument as a failed request
252
+ this.luvio.instrument(() => {
253
+ return {
254
+ [ADAPTER_UNFULFILLED_ERROR]: true,
255
+ adapterName: this.adapter.name,
256
+ missingPaths: snapshot.missingPaths,
257
+ missingLinks: snapshot.missingLinks,
258
+ };
259
+ });
260
+ return;
261
+ }
262
+ // if config has changed before the snapshot arrives then ignore snapshot
263
+ if (this.config !== configForSnapshot) {
264
+ return;
265
+ }
266
+ // emit unless snapshot is pending
267
+ if (isFulfilledSnapshot(snapshot) ||
268
+ isErrorSnapshot(snapshot) ||
269
+ isStaleSnapshot(snapshot)) {
270
+ this.emit(snapshot);
271
+ }
272
+ // subscribe to the new snapshot
273
+ this.subscribe(snapshot);
274
+ };
275
+ // Data resolved sync
276
+ if (!isPromise(snapshotOrPromise)) {
277
+ emitAndSubscribe(snapshotOrPromise);
278
+ }
279
+ else {
280
+ // We want to let errors from this promise propagate to the app container,
281
+ // which is why we do not have a reject handler here.
282
+ // If an error is thrown here, it means that there was an error somewhere
283
+ // inside an adapter which means that there was a mistake by the implementor.
284
+ // Errors that come from the network should never hit this block because
285
+ // they are treated like regular snapshots, not true error paths.
286
+ snapshotOrPromise.then(emitAndSubscribe, (error) => throwAnnotatedError(error, ADAPTER_SNAPSHOT_REJECTED_MESSAGE));
287
+ }
288
+ }
289
+ /**
290
+ * Emits new values to the callback.
291
+ *
292
+ * @param snapshot Snapshot to be emitted, if omitted then undefineds will be emitted
293
+ */
294
+ emit(snapshot) {
295
+ const payload = snapshotToPayload$1(snapshot);
296
+ dataToTupleWeakMap.set(payload, [this.name, snapshot]);
297
+ try {
298
+ this.callback(payload);
299
+ }
300
+ catch (error) {
301
+ if (error instanceof Error) {
302
+ throwAnnotatedError(error, USERLAND_PROVISION_ERROR_MESSAGE);
303
+ }
304
+ }
305
+ }
306
+ /**
307
+ * Subscribes this wire adapter to future changes to the specified snapshot. Any changes
308
+ * to the snapshot will be automatically emitted to the component.
309
+ *
310
+ * @param snapshot Snapshot
311
+ * @param subscriptionCallback callback
312
+ */
313
+ subscribe(snapshot) {
314
+ // always clean up any old subscription that we might have
315
+ this.unsubscribe();
316
+ // but only subscribe if component is currently connected
317
+ if (this.connected) {
318
+ this.unsubscriber = this.luvio.storeSubscribe(snapshot, this.emit.bind(this));
319
+ }
320
+ }
321
+ /**
322
+ * Deletes this wire adapter's snapshot subscription (if any).
323
+ */
324
+ unsubscribe() {
325
+ // clean up subscription
326
+ if (this.unsubscriber !== undefined) {
327
+ this.unsubscriber();
328
+ this.unsubscriber = undefined;
329
+ }
330
+ }
331
+ }
332
+ /**
333
+ * Wraps a luvio Adapter in a WireAdapterConstructor that conforms to https://rfcs.lwc.dev/rfcs/lwc/0000-wire-reform#wire-adapter-protocol.
334
+ *
335
+ * @param adapter Adapter
336
+ * @param name name to assign to the generated constructor
337
+ * @param luvio Luvio
338
+ */
339
+ function createWireAdapterConstructor(adapter, name, luvio) {
340
+ const constructor = function (callback) {
341
+ const delegate = new LWCLuvioWireAdapter(adapter, name, luvio, callback);
342
+ this.connect = () => delegate.connect();
343
+ this.disconnect = () => delegate.disconnect();
344
+ this.update = (config, context) => delegate.update(config, context);
345
+ };
346
+ Object.defineProperty(constructor, 'name', { value: name });
347
+ return constructor;
348
348
  }
349
349
 
350
- class LWCInfinteScrollingLuvioWireAdapter extends LWCLuvioWireAdapter {
351
- /**
352
- * Called when the component associated with the wire adapter is connected.
353
- */
354
- connect() {
355
- this.connectTimestamp = Date.now();
356
- super.connect();
357
- }
358
- /**
359
- * Called when the component associated with the wire adapter is disconnected.
360
- */
361
- disconnect() {
362
- this.connectTimestamp = undefined;
363
- super.disconnect();
364
- }
365
- /**
366
- * Called when new or updated config is supplied to the wire adapter.
367
- *
368
- * @param config new config parameters for the wire adapter
369
- * @param context context for the wire adapter
370
- */
371
- update(config, context) {
372
- if (this.connectTimestamp) {
373
- const mergedContext = Object.assign({
374
- cachePolicy: {
375
- type: 'valid-at',
376
- timestamp: this.connectTimestamp,
377
- },
378
- }, context);
379
- super.unsubscribe();
380
- this.config = sanitize(config);
381
- this.callAdapterWithContext(mergedContext);
382
- }
383
- else {
384
- super.update(config, context);
385
- }
386
- }
387
- /**
388
- * Calls the adapter if config has been set and the component is connected.
389
- */
390
- callAdapterWithContext(context) {
391
- if (!this.connected || this.config === undefined) {
392
- return;
393
- }
394
- const snapshotOrPromise = this.adapter(this.config, context);
395
- super.processAdapterResponse(snapshotOrPromise);
396
- }
397
- }
398
- function createInfiniteScrollingWireAdapterConstructor(adapter, name, luvio) {
399
- const constructor = function (callback) {
400
- const delegate = new LWCInfinteScrollingLuvioWireAdapter(adapter, name, luvio, callback);
401
- this.connect = () => delegate.connect();
402
- this.disconnect = () => delegate.disconnect();
403
- this.update = (config, context) => delegate.update(config, context);
404
- };
405
- Object.defineProperty(constructor, 'name', { value: name });
406
- return constructor;
350
+ class LWCInfinteScrollingLuvioWireAdapter extends LWCLuvioWireAdapter {
351
+ /**
352
+ * Called when the component associated with the wire adapter is connected.
353
+ */
354
+ connect() {
355
+ this.connectTimestamp = Date.now();
356
+ super.connect();
357
+ }
358
+ /**
359
+ * Called when the component associated with the wire adapter is disconnected.
360
+ */
361
+ disconnect() {
362
+ this.connectTimestamp = undefined;
363
+ super.disconnect();
364
+ }
365
+ /**
366
+ * Called when new or updated config is supplied to the wire adapter.
367
+ *
368
+ * @param config new config parameters for the wire adapter
369
+ * @param context context for the wire adapter
370
+ */
371
+ update(config, context) {
372
+ if (this.connectTimestamp) {
373
+ const mergedContext = Object.assign({
374
+ cachePolicy: {
375
+ type: 'valid-at',
376
+ timestamp: this.connectTimestamp,
377
+ },
378
+ }, context);
379
+ super.unsubscribe();
380
+ this.config = sanitize(config);
381
+ this.callAdapterWithContext(mergedContext);
382
+ }
383
+ else {
384
+ super.update(config, context);
385
+ }
386
+ }
387
+ /**
388
+ * Calls the adapter if config has been set and the component is connected.
389
+ */
390
+ callAdapterWithContext(context) {
391
+ if (!this.connected || this.config === undefined) {
392
+ return;
393
+ }
394
+ const snapshotOrPromise = this.adapter(this.config, context);
395
+ super.processAdapterResponse(snapshotOrPromise);
396
+ }
397
+ }
398
+ function createInfiniteScrollingWireAdapterConstructor(adapter, name, luvio) {
399
+ const constructor = function (callback) {
400
+ const delegate = new LWCInfinteScrollingLuvioWireAdapter(adapter, name, luvio, callback);
401
+ this.connect = () => delegate.connect();
402
+ this.disconnect = () => delegate.disconnect();
403
+ this.update = (config, context) => delegate.update(config, context);
404
+ };
405
+ Object.defineProperty(constructor, 'name', { value: name });
406
+ return constructor;
407
407
  }
408
408
 
409
- function snapshotToPayload(snapshot) {
410
- const payload = {
411
- data: undefined,
412
- errors: undefined,
413
- };
414
- if (snapshot === undefined) {
415
- return payload;
416
- }
417
- payload.data = extractSnapshotData(snapshot);
418
- // TODO handle batch error scenarios.
419
- if ('error' in snapshot && snapshot.error !== undefined) {
420
- if (Array.isArray(snapshot.error)) {
421
- payload.errors = snapshot.error;
422
- }
423
- else {
424
- payload.errors = [snapshot.error];
425
- }
426
- }
427
- return payload;
428
- }
429
- class LWCGraphQLLuvioWireAdapter extends LWCLuvioWireAdapter {
430
- constructor(adapter, name, luvio, astResolver, callback) {
431
- super(adapter, name, luvio, callback);
432
- this.astResolver = astResolver;
433
- }
434
- update(config, _context) {
435
- this.unsubscribe();
436
- if (config.batchQuery) {
437
- this.config = {
438
- batchQuery: config.batchQuery.map((individualConfig) => safeSanitizeGraphQLConfigObject(individualConfig)),
439
- };
440
- }
441
- else {
442
- this.config = safeSanitizeGraphQLConfigObject(config);
443
- }
444
- this.callAdapter();
445
- }
446
- /**
447
- * Emits new values to the callback.
448
- *
449
- * @param snapshot Snapshot to be emitted, if omitted then undefineds will be emitted
450
- */
451
- emit(snapshot) {
452
- const payload = snapshotToPayload(snapshot);
453
- dataToTupleWeakMap.set(payload, [this.name, snapshot]);
454
- try {
455
- this.callback(payload);
456
- }
457
- catch (error) {
458
- if (error instanceof Error) {
459
- throwAnnotatedError(error, USERLAND_PROVISION_ERROR_MESSAGE);
460
- }
461
- }
462
- }
463
- /**
464
- * Coerce config before calling the adapter, preserve current behavior otherwise
465
- */
466
- callAdapter() {
467
- if (!this.connected || this.config === undefined) {
468
- return;
469
- }
470
- const config = this.config;
471
- if ('batchQuery' in config) {
472
- const batchConfig = {
473
- batchQuery: config.batchQuery.map((individualConfig) => this.resolveQueryAst(individualConfig)),
474
- };
475
- // If any of the configurations are invalid, we bail out of calling the adapter.
476
- if (batchConfig.batchQuery.some((val) => val === undefined)) {
477
- return;
478
- }
479
- const snapshotOrPromise = this.adapter(batchConfig);
480
- this.processAdapterResponse(snapshotOrPromise);
481
- }
482
- else if ('query' in config) {
483
- const singleConfig = this.resolveQueryAst(config);
484
- if (singleConfig !== undefined) {
485
- const snapshotOrPromise = this.adapter(singleConfig);
486
- this.processAdapterResponse(snapshotOrPromise);
487
- }
488
- }
489
- }
490
- resolveQueryAst(config) {
491
- if (config.query === null) {
492
- return;
493
- }
494
- const ast = this.astResolver(config.query);
495
- if (ast === undefined && config.query !== undefined) {
496
- // this should only happen if the user didn't parse the query
497
- if (process.env.NODE_ENV !== 'production') {
498
- throw new Error(USERLAND_GRAPHQL_PARSER_ERROR_MESSAGE);
499
- }
500
- return;
501
- }
502
- const resolvedAdapterConfig = {
503
- ...config,
504
- query: ast,
505
- };
506
- return resolvedAdapterConfig;
507
- }
508
- }
509
- function extractSnapshotData(snapshot) {
510
- if ('data' in snapshot && snapshot.data !== undefined) {
511
- const isSingleGraphQLData = 'data' in snapshot.data && snapshot.data.data !== undefined;
512
- const isBatchGraphQLData = 'results' in snapshot.data && snapshot.data.results !== undefined;
513
- if (isSingleGraphQLData)
514
- return snapshot.data.data;
515
- if (isBatchGraphQLData)
516
- return snapshot.data;
517
- }
518
- }
519
- /**
520
- * Wraps a luvio Adapter in a WireAdapterConstructor that conforms to https://rfcs.lwc.dev/rfcs/lwc/0000-wire-reform#wire-adapter-protocol.
521
- *
522
- * @param adapter Adapter
523
- * @param name name to assign to the generated constructor
524
- * @param luvio Luvio
525
- */
526
- function createGraphQLWireAdapterConstructor(adapter, name, luvio, astResolver) {
527
- const constructor = function (callback) {
528
- const delegate = new LWCGraphQLLuvioWireAdapter(adapter, name, luvio, astResolver, callback);
529
- this.connect = () => delegate.connect();
530
- this.disconnect = () => delegate.disconnect();
531
- this.update = (config, context) => delegate.update(config, context);
532
- };
533
- Object.defineProperty(constructor, 'name', { value: name });
534
- return constructor;
535
- }
536
- function safeSanitizeGraphQLConfigObject(config) {
537
- // graphql query AST is passed by reference
538
- // sanitizing it makes a copy and we lose that reference
539
- // so we avoid sanitizing it
540
- return {
541
- ...sanitize(config),
542
- query: config.query,
543
- };
409
+ function snapshotToPayload(snapshot) {
410
+ const payload = {
411
+ data: undefined,
412
+ errors: undefined,
413
+ };
414
+ if (snapshot === undefined) {
415
+ return payload;
416
+ }
417
+ payload.data = extractSnapshotData(snapshot);
418
+ // TODO handle batch error scenarios.
419
+ if ('error' in snapshot && snapshot.error !== undefined) {
420
+ if (Array.isArray(snapshot.error)) {
421
+ payload.errors = snapshot.error;
422
+ }
423
+ else {
424
+ payload.errors = [snapshot.error];
425
+ }
426
+ }
427
+ return payload;
428
+ }
429
+ class LWCGraphQLLuvioWireAdapter extends LWCLuvioWireAdapter {
430
+ constructor(adapter, name, luvio, astResolver, callback) {
431
+ super(adapter, name, luvio, callback);
432
+ this.astResolver = astResolver;
433
+ }
434
+ update(config, _context) {
435
+ this.unsubscribe();
436
+ if (config.batchQuery) {
437
+ this.config = {
438
+ batchQuery: config.batchQuery.map((individualConfig) => safeSanitizeGraphQLConfigObject(individualConfig)),
439
+ };
440
+ }
441
+ else {
442
+ this.config = safeSanitizeGraphQLConfigObject(config);
443
+ }
444
+ this.callAdapter();
445
+ }
446
+ /**
447
+ * Emits new values to the callback.
448
+ *
449
+ * @param snapshot Snapshot to be emitted, if omitted then undefineds will be emitted
450
+ */
451
+ emit(snapshot) {
452
+ const payload = snapshotToPayload(snapshot);
453
+ dataToTupleWeakMap.set(payload, [this.name, snapshot]);
454
+ try {
455
+ this.callback(payload);
456
+ }
457
+ catch (error) {
458
+ if (error instanceof Error) {
459
+ throwAnnotatedError(error, USERLAND_PROVISION_ERROR_MESSAGE);
460
+ }
461
+ }
462
+ }
463
+ /**
464
+ * Coerce config before calling the adapter, preserve current behavior otherwise
465
+ */
466
+ callAdapter() {
467
+ if (!this.connected || this.config === undefined) {
468
+ return;
469
+ }
470
+ const config = this.config;
471
+ if ('batchQuery' in config) {
472
+ const batchConfig = {
473
+ batchQuery: config.batchQuery.map((individualConfig) => this.resolveQueryAst(individualConfig)),
474
+ };
475
+ // If any of the configurations are invalid, we bail out of calling the adapter.
476
+ if (batchConfig.batchQuery.some((val) => val === undefined)) {
477
+ return;
478
+ }
479
+ const snapshotOrPromise = this.adapter(batchConfig);
480
+ this.processAdapterResponse(snapshotOrPromise);
481
+ }
482
+ else if ('query' in config) {
483
+ const singleConfig = this.resolveQueryAst(config);
484
+ if (singleConfig !== undefined) {
485
+ const snapshotOrPromise = this.adapter(singleConfig);
486
+ this.processAdapterResponse(snapshotOrPromise);
487
+ }
488
+ }
489
+ }
490
+ resolveQueryAst(config) {
491
+ if (config.query === null) {
492
+ return;
493
+ }
494
+ const ast = this.astResolver(config.query);
495
+ if (ast === undefined && config.query !== undefined) {
496
+ // this should only happen if the user didn't parse the query
497
+ if (process.env.NODE_ENV !== 'production') {
498
+ throw new Error(USERLAND_GRAPHQL_PARSER_ERROR_MESSAGE);
499
+ }
500
+ return;
501
+ }
502
+ const resolvedAdapterConfig = {
503
+ ...config,
504
+ query: ast,
505
+ };
506
+ return resolvedAdapterConfig;
507
+ }
508
+ }
509
+ function extractSnapshotData(snapshot) {
510
+ if ('data' in snapshot && snapshot.data !== undefined) {
511
+ const isSingleGraphQLData = 'data' in snapshot.data && snapshot.data.data !== undefined;
512
+ const isBatchGraphQLData = 'results' in snapshot.data && snapshot.data.results !== undefined;
513
+ if (isSingleGraphQLData)
514
+ return snapshot.data.data;
515
+ if (isBatchGraphQLData)
516
+ return snapshot.data;
517
+ }
518
+ }
519
+ /**
520
+ * Wraps a luvio Adapter in a WireAdapterConstructor that conforms to https://rfcs.lwc.dev/rfcs/lwc/0000-wire-reform#wire-adapter-protocol.
521
+ *
522
+ * @param adapter Adapter
523
+ * @param name name to assign to the generated constructor
524
+ * @param luvio Luvio
525
+ */
526
+ function createGraphQLWireAdapterConstructor(adapter, name, luvio, astResolver) {
527
+ const constructor = function (callback) {
528
+ const delegate = new LWCGraphQLLuvioWireAdapter(adapter, name, luvio, astResolver, callback);
529
+ this.connect = () => delegate.connect();
530
+ this.disconnect = () => delegate.disconnect();
531
+ this.update = (config, context) => delegate.update(config, context);
532
+ };
533
+ Object.defineProperty(constructor, 'name', { value: name });
534
+ return constructor;
535
+ }
536
+ function safeSanitizeGraphQLConfigObject(config) {
537
+ // graphql query AST is passed by reference
538
+ // sanitizing it makes a copy and we lose that reference
539
+ // so we avoid sanitizing it
540
+ return {
541
+ ...sanitize(config),
542
+ query: config.query,
543
+ };
544
544
  }
545
545
 
546
546
  export { ADAPTER_UNFULFILLED_ERROR, REFRESH_ADAPTER_EVENT, bindWireRefresh, createGraphQLWireAdapterConstructor, createInfiniteScrollingWireAdapterConstructor, createWireAdapterConstructor, refreshData };