@salesforce/lds-bindings 0.131.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/LICENSE.txt +82 -0
- package/dist/ldsBindings.js +933 -0
- package/dist/types/bindWireRefresh.d.ts +7 -0
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/graphQLImperativeAdapter.d.ts +32 -0
- package/dist/types/imperativeAdapter.d.ts +31 -0
- package/dist/types/instrumentation.d.ts +29 -0
- package/dist/types/instrumentedAdapter.d.ts +3 -0
- package/dist/types/ldsAdapter.d.ts +7 -0
- package/dist/types/main.d.ts +9 -0
- package/dist/types/utils/lanugage.d.ts +5 -0
- package/dist/types/utils/snapshotType.d.ts +3 -0
- package/dist/types/utils/utils.d.ts +1 -0
- package/dist/types/wireAdapter.d.ts +7 -0
- package/package.json +39 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Terms of Use
|
|
2
|
+
|
|
3
|
+
Copyright 2022 Salesforce, Inc. All rights reserved.
|
|
4
|
+
|
|
5
|
+
These Terms of Use govern the download, installation, and/or use of this
|
|
6
|
+
software provided by Salesforce, Inc. ("Salesforce") (the "Software"), were
|
|
7
|
+
last updated on April 15, 2022, and constitute a legally binding
|
|
8
|
+
agreement between you and Salesforce. If you do not agree to these Terms of
|
|
9
|
+
Use, do not install or use the Software.
|
|
10
|
+
|
|
11
|
+
Salesforce grants you a worldwide, non-exclusive, no-charge, royalty-free
|
|
12
|
+
copyright license to reproduce, prepare derivative works of, publicly
|
|
13
|
+
display, publicly perform, sublicense, and distribute the Software and
|
|
14
|
+
derivative works subject to these Terms. These Terms shall be included in
|
|
15
|
+
all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
Subject to the limited rights expressly granted hereunder, Salesforce
|
|
18
|
+
reserves all rights, title, and interest in and to all intellectual
|
|
19
|
+
property subsisting in the Software. No rights are granted to you hereunder
|
|
20
|
+
other than as expressly set forth herein. Users residing in countries on
|
|
21
|
+
the United States Office of Foreign Assets Control sanction list, or which
|
|
22
|
+
are otherwise subject to a US export embargo, may not use the Software.
|
|
23
|
+
|
|
24
|
+
Implementation of the Software may require development work, for which you
|
|
25
|
+
are responsible. The Software may contain bugs, errors and
|
|
26
|
+
incompatibilities and is made available on an AS IS basis without support,
|
|
27
|
+
updates, or service level commitments.
|
|
28
|
+
|
|
29
|
+
Salesforce reserves the right at any time to modify, suspend, or
|
|
30
|
+
discontinue, the Software (or any part thereof) with or without notice. You
|
|
31
|
+
agree that Salesforce shall not be liable to you or to any third party for
|
|
32
|
+
any modification, suspension, or discontinuance.
|
|
33
|
+
|
|
34
|
+
You agree to defend Salesforce against any claim, demand, suit or
|
|
35
|
+
proceeding made or brought against Salesforce by a third party arising out
|
|
36
|
+
of or accruing from (a) your use of the Software, and (b) any application
|
|
37
|
+
you develop with the Software that infringes any copyright, trademark,
|
|
38
|
+
trade secret, trade dress, patent, or other intellectual property right of
|
|
39
|
+
any person or defames any person or violates their rights of publicity or
|
|
40
|
+
privacy (each a "Claim Against Salesforce"), and will indemnify Salesforce
|
|
41
|
+
from any damages, attorney fees, and costs finally awarded against
|
|
42
|
+
Salesforce as a result of, or for any amounts paid by Salesforce under a
|
|
43
|
+
settlement approved by you in writing of, a Claim Against Salesforce,
|
|
44
|
+
provided Salesforce (x) promptly gives you written notice of the Claim
|
|
45
|
+
Against Salesforce, (y) gives you sole control of the defense and
|
|
46
|
+
settlement of the Claim Against Salesforce (except that you may not settle
|
|
47
|
+
any Claim Against Salesforce unless it unconditionally releases Salesforce
|
|
48
|
+
of all liability), and (z) gives you all reasonable assistance, at your
|
|
49
|
+
expense.
|
|
50
|
+
|
|
51
|
+
WITHOUT LIMITING THE GENERALITY OF THE FOREGOING, THE SOFTWARE IS NOT
|
|
52
|
+
SUPPORTED AND IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
53
|
+
IMPLIED. IN NO EVENT SHALL SALESFORCE HAVE ANY LIABILITY FOR ANY DAMAGES,
|
|
54
|
+
INCLUDING, BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
|
|
55
|
+
PUNITIVE, OR CONSEQUENTIAL DAMAGES, OR DAMAGES BASED ON LOST PROFITS, DATA,
|
|
56
|
+
OR USE, IN CONNECTION WITH THE SOFTWARE, HOWEVER CAUSED AND WHETHER IN
|
|
57
|
+
CONTRACT, TORT, OR UNDER ANY OTHER THEORY OF LIABILITY, WHETHER OR NOT YOU
|
|
58
|
+
HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
59
|
+
|
|
60
|
+
These Terms of Use shall be governed exclusively by the internal laws of
|
|
61
|
+
the State of California, without regard to its conflicts of laws
|
|
62
|
+
rules. Each party hereby consents to the exclusive jurisdiction of the
|
|
63
|
+
state and federal courts located in San Francisco County, California to
|
|
64
|
+
adjudicate any dispute arising out of or relating to these Terms of Use and
|
|
65
|
+
the download, installation, and/or use of the Software. Except as expressly
|
|
66
|
+
stated herein, these Terms of Use constitute the entire agreement between
|
|
67
|
+
the parties, and supersede all prior and contemporaneous agreements,
|
|
68
|
+
proposals, or representations, written or oral, concerning their subject
|
|
69
|
+
matter. No modification, amendment, or waiver of any provision of these
|
|
70
|
+
Terms of Use shall be effective unless it is by an update to these Terms of
|
|
71
|
+
Use that Salesforce makes available, or is in writing and signed by the
|
|
72
|
+
party against whom the modification, amendment, or waiver is to be
|
|
73
|
+
asserted.
|
|
74
|
+
|
|
75
|
+
Data Privacy: Salesforce may collect, process, and store device,
|
|
76
|
+
system, and other information related to your use of the Software. This
|
|
77
|
+
information includes, but is not limited to, IP address, user metrics, and
|
|
78
|
+
other data ("Usage Data"). Salesforce may use Usage Data for analytics,
|
|
79
|
+
product development, and marketing purposes. You acknowledge that files
|
|
80
|
+
generated in conjunction with the Software may contain sensitive or
|
|
81
|
+
confidential data, and you are solely responsible for anonymizing and
|
|
82
|
+
protecting such data.
|
|
@@ -0,0 +1,933 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2022, Salesforce, Inc.,
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* For full license text, see the LICENSE.txt file
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* *******************************************************************************************
|
|
8
|
+
* ATTENTION!
|
|
9
|
+
* THIS IS A GENERATED FILE FROM https://github.com/salesforce-experience-platform-emu/lds-lightning-platform
|
|
10
|
+
* If you would like to contribute to LDS, please follow the steps outlined in the git repo.
|
|
11
|
+
* Any changes made to this file in p4 will be automatically overwritten.
|
|
12
|
+
* *******************************************************************************************
|
|
13
|
+
*/
|
|
14
|
+
/* proxy-compat-disable */
|
|
15
|
+
import { unwrap } from 'lwc';
|
|
16
|
+
|
|
17
|
+
// instrumentation keys to be imported by ldsInstrumentation
|
|
18
|
+
const REFRESH_ADAPTER_EVENT = 'refresh-adapter-event';
|
|
19
|
+
const ADAPTER_UNFULFILLED_ERROR = 'adapter-unfulfilled-error';
|
|
20
|
+
const USERLAND_PROVISION_ERROR_MESSAGE = "LWC component's @wire target property or method threw an error during value provisioning. Original error:";
|
|
21
|
+
const ADAPTER_SNAPSHOT_REJECTED_MESSAGE = 'Luvio wire adapter Promise<Snapshot> rejected. Original error:';
|
|
22
|
+
const USERLAND_GRAPHQL_PARSER_ERROR_MESSAGE = 'Use `gql` parser to parse your "query" string';
|
|
23
|
+
|
|
24
|
+
// map of emitted object -> [ adapter name, snapshot ]; snapshot is only undefined for the
|
|
25
|
+
// initially-emitted { data: undefined, error: undefined } value
|
|
26
|
+
const dataToTupleWeakMap = new WeakMap();
|
|
27
|
+
|
|
28
|
+
var SnapshotState$1;
|
|
29
|
+
(function (SnapshotState) {
|
|
30
|
+
SnapshotState["Fulfilled"] = "Fulfilled";
|
|
31
|
+
SnapshotState["Unfulfilled"] = "Unfulfilled";
|
|
32
|
+
SnapshotState["Error"] = "Error";
|
|
33
|
+
SnapshotState["Pending"] = "Pending";
|
|
34
|
+
SnapshotState["Stale"] = "Stale";
|
|
35
|
+
})(SnapshotState$1 || (SnapshotState$1 = {}));
|
|
36
|
+
function isErrorSnapshot$1(snapshot) {
|
|
37
|
+
return snapshot.state === SnapshotState$1.Error;
|
|
38
|
+
}
|
|
39
|
+
function isFulfilledSnapshot(snapshot) {
|
|
40
|
+
return snapshot.state === SnapshotState$1.Fulfilled;
|
|
41
|
+
}
|
|
42
|
+
function isStaleSnapshot(snapshot) {
|
|
43
|
+
return snapshot.state === SnapshotState$1.Stale;
|
|
44
|
+
}
|
|
45
|
+
function isUnfulfilledSnapshot(snapshot) {
|
|
46
|
+
return snapshot.state === SnapshotState$1.Unfulfilled;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Transform a Snapshot into a payload suitable for passing to a DataCallback.
|
|
50
|
+
*
|
|
51
|
+
* @param snapshot Snapshot
|
|
52
|
+
*/
|
|
53
|
+
function snapshotToPayload$1(snapshot) {
|
|
54
|
+
if (snapshot === undefined) {
|
|
55
|
+
return {
|
|
56
|
+
data: undefined,
|
|
57
|
+
error: undefined,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (isErrorSnapshot$1(snapshot)) {
|
|
61
|
+
return {
|
|
62
|
+
data: undefined,
|
|
63
|
+
error: snapshot.error,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// fulfilled or stale
|
|
67
|
+
return {
|
|
68
|
+
data: snapshot.data,
|
|
69
|
+
error: undefined,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function bindWireRefresh$1(luvio) {
|
|
74
|
+
return function refresh(data) {
|
|
75
|
+
return refreshData(data, dataToTupleWeakMap, luvio);
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function refreshData(data, dataToTuple, luvio) {
|
|
79
|
+
const tuple = dataToTuple.get(unwrap(data));
|
|
80
|
+
if (tuple === undefined) {
|
|
81
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
82
|
+
throw new Error('Refresh failed because resolved configuration is not available.');
|
|
83
|
+
}
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const [adapterName, snapshot] = tuple;
|
|
87
|
+
luvio.instrument(() => {
|
|
88
|
+
return {
|
|
89
|
+
[REFRESH_ADAPTER_EVENT]: true,
|
|
90
|
+
adapterName,
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
// snapshot is undefined when a caller refreshes the initial
|
|
94
|
+
// { data: undefined, error: undefined } object that we emitted
|
|
95
|
+
if (snapshot === undefined) {
|
|
96
|
+
return Promise.resolve(undefined);
|
|
97
|
+
}
|
|
98
|
+
return luvio.refreshSnapshot(snapshot).then((refreshed) => {
|
|
99
|
+
if (isErrorSnapshot$1(refreshed)) {
|
|
100
|
+
throw refreshed.error;
|
|
101
|
+
}
|
|
102
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
103
|
+
if (isUnfulfilledSnapshot(refreshed)) {
|
|
104
|
+
throw new Error('Refresh resulted in unfulfilled snapshot');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const { freeze, keys } = Object;
|
|
112
|
+
const { isArray } = Array;
|
|
113
|
+
const { stringify } = JSON;
|
|
114
|
+
|
|
115
|
+
function isPromise$1(value) {
|
|
116
|
+
// check for Thenable due to test frameworks using custom Promise impls
|
|
117
|
+
return value.then !== undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* (Re)throws an error after adding a prefix to the message.
|
|
122
|
+
*
|
|
123
|
+
* @param error Error
|
|
124
|
+
* @param messagePrefix prefix to add to error's message
|
|
125
|
+
*/
|
|
126
|
+
function throwAnnotatedError(error, messagePrefix) {
|
|
127
|
+
if (error instanceof Error) {
|
|
128
|
+
error.message = `${messagePrefix}\n[${error.message}]`;
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
throw new Error(`${messagePrefix}\n[${stringify(error)}]`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
class Sanitizer {
|
|
135
|
+
constructor(obj) {
|
|
136
|
+
this.obj = obj;
|
|
137
|
+
this.copy = {};
|
|
138
|
+
this.currentPath = {
|
|
139
|
+
key: '',
|
|
140
|
+
value: obj,
|
|
141
|
+
parent: null,
|
|
142
|
+
data: this.copy,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
sanitize() {
|
|
146
|
+
const sanitizer = this;
|
|
147
|
+
stringify(this.obj, function (key, value) {
|
|
148
|
+
if (key === '') {
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
151
|
+
const parent = this;
|
|
152
|
+
if (parent !== sanitizer.currentPath.value) {
|
|
153
|
+
sanitizer.exit(parent);
|
|
154
|
+
}
|
|
155
|
+
if (typeof value === 'object' && value !== null) {
|
|
156
|
+
sanitizer.enter(key, value);
|
|
157
|
+
return value;
|
|
158
|
+
}
|
|
159
|
+
sanitizer.currentPath.data[key] = value;
|
|
160
|
+
return value;
|
|
161
|
+
});
|
|
162
|
+
return this.copy;
|
|
163
|
+
}
|
|
164
|
+
enter(key, value) {
|
|
165
|
+
const { currentPath: parentPath } = this;
|
|
166
|
+
const data = (parentPath.data[key] = isArray(value) ? [] : {});
|
|
167
|
+
this.currentPath = {
|
|
168
|
+
key,
|
|
169
|
+
value,
|
|
170
|
+
parent: parentPath,
|
|
171
|
+
data,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
exit(parent) {
|
|
175
|
+
while (this.currentPath.value !== parent) {
|
|
176
|
+
this.currentPath = this.currentPath.parent || this.currentPath;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Returns a sanitized version of an object by recursively unwrapping the Proxies.
|
|
182
|
+
*
|
|
183
|
+
* In order to keep luvio performance optimal on IE11, we need to make sure that luvio code gets
|
|
184
|
+
* transformed by the es5-proxy-compat. At the same time we need to ensure that no ProxyCompat leaks
|
|
185
|
+
* into the luvio engine code nor into the adapters. All the data coming from LWC-land need to be
|
|
186
|
+
* sanitized first.
|
|
187
|
+
*/
|
|
188
|
+
function sanitize(obj) {
|
|
189
|
+
return new Sanitizer(obj).sanitize();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
class LWCLuvioWireAdapter {
|
|
193
|
+
/**
|
|
194
|
+
* Constructs a new wire adapter instance for the given adapter.
|
|
195
|
+
*
|
|
196
|
+
* @param callback callback to be invoked with new values
|
|
197
|
+
*/
|
|
198
|
+
constructor(adapter, name, luvio, callback) {
|
|
199
|
+
// a component can be connected-disconnected-reconnected multiple times during its
|
|
200
|
+
// life but we only want to keep subscriptions active while it is connected; the
|
|
201
|
+
// connect/disconnect methods below keep this value updated to reflect the current
|
|
202
|
+
// state
|
|
203
|
+
this.connected = false;
|
|
204
|
+
this.adapter = adapter;
|
|
205
|
+
this.name = name;
|
|
206
|
+
this.luvio = luvio;
|
|
207
|
+
this.callback = callback;
|
|
208
|
+
// initialize the wired property with a properly shaped object so cmps can use <template if:true={wiredProperty.data}>
|
|
209
|
+
this.emit();
|
|
210
|
+
}
|
|
211
|
+
// WireAdapter interface methods
|
|
212
|
+
/**
|
|
213
|
+
* Called when the component associated with the wire adapter is connected.
|
|
214
|
+
*/
|
|
215
|
+
connect() {
|
|
216
|
+
this.connected = true;
|
|
217
|
+
this.callAdapter();
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Called when the component associated with the wire adapter is disconnected.
|
|
221
|
+
*/
|
|
222
|
+
disconnect() {
|
|
223
|
+
this.unsubscribe();
|
|
224
|
+
this.connected = false;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Called when new or updated config is supplied to the wire adapter.
|
|
228
|
+
*
|
|
229
|
+
* @param config new config parameters for the wire adapter
|
|
230
|
+
* @param _context not used
|
|
231
|
+
*/
|
|
232
|
+
update(config, _context) {
|
|
233
|
+
this.unsubscribe();
|
|
234
|
+
this.config = sanitize(config);
|
|
235
|
+
this.callAdapter();
|
|
236
|
+
}
|
|
237
|
+
// private and protected utility methods
|
|
238
|
+
/**
|
|
239
|
+
* Calls the adapter if config has been set and the component is connected.
|
|
240
|
+
*/
|
|
241
|
+
callAdapter() {
|
|
242
|
+
if (!this.connected || this.config === undefined) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const snapshotOrPromise = this.adapter(this.config);
|
|
246
|
+
this.processAdapterResponse(snapshotOrPromise);
|
|
247
|
+
}
|
|
248
|
+
processAdapterResponse(snapshotOrPromise) {
|
|
249
|
+
// insufficient config, wait for new config from component
|
|
250
|
+
if (snapshotOrPromise === null) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const configForSnapshot = this.config;
|
|
254
|
+
const emitAndSubscribe = (snapshot) => {
|
|
255
|
+
// adapters leveraging adapter context could asynchronously
|
|
256
|
+
// return null (due to invalid config)
|
|
257
|
+
if (snapshot === null) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
// We should never broadcast an unfulfilled snapshot to a component
|
|
261
|
+
if (isUnfulfilledSnapshot(snapshot)) {
|
|
262
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
263
|
+
throw new Error(`Unfulfilled snapshot emitted to component from subscription, missingPaths: ${keys(snapshot.missingPaths)}`);
|
|
264
|
+
}
|
|
265
|
+
// Instrument as a failed request
|
|
266
|
+
this.luvio.instrument(() => {
|
|
267
|
+
return {
|
|
268
|
+
[ADAPTER_UNFULFILLED_ERROR]: true,
|
|
269
|
+
adapterName: this.adapter.name,
|
|
270
|
+
missingPaths: snapshot.missingPaths,
|
|
271
|
+
missingLinks: snapshot.missingLinks,
|
|
272
|
+
};
|
|
273
|
+
});
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// if config has changed before the snapshot arrives then ignore snapshot
|
|
277
|
+
if (this.config !== configForSnapshot) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// emit unless snapshot is pending
|
|
281
|
+
if (isFulfilledSnapshot(snapshot) ||
|
|
282
|
+
isErrorSnapshot$1(snapshot) ||
|
|
283
|
+
isStaleSnapshot(snapshot)) {
|
|
284
|
+
this.emit(snapshot);
|
|
285
|
+
}
|
|
286
|
+
// subscribe to the new snapshot
|
|
287
|
+
this.subscribe(snapshot);
|
|
288
|
+
};
|
|
289
|
+
// Data resolved sync
|
|
290
|
+
if (!isPromise$1(snapshotOrPromise)) {
|
|
291
|
+
emitAndSubscribe(snapshotOrPromise);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
// We want to let errors from this promise propagate to the app container,
|
|
295
|
+
// which is why we do not have a reject handler here.
|
|
296
|
+
// If an error is thrown here, it means that there was an error somewhere
|
|
297
|
+
// inside an adapter which means that there was a mistake by the implementor.
|
|
298
|
+
// Errors that come from the network should never hit this block because
|
|
299
|
+
// they are treated like regular snapshots, not true error paths.
|
|
300
|
+
snapshotOrPromise.then(emitAndSubscribe, (error) => throwAnnotatedError(error, ADAPTER_SNAPSHOT_REJECTED_MESSAGE));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Emits new values to the callback.
|
|
305
|
+
*
|
|
306
|
+
* @param snapshot Snapshot to be emitted, if omitted then undefineds will be emitted
|
|
307
|
+
*/
|
|
308
|
+
emit(snapshot) {
|
|
309
|
+
const payload = snapshotToPayload$1(snapshot);
|
|
310
|
+
dataToTupleWeakMap.set(payload, [this.name, snapshot]);
|
|
311
|
+
try {
|
|
312
|
+
this.callback(payload);
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
if (error instanceof Error) {
|
|
316
|
+
throwAnnotatedError(error, USERLAND_PROVISION_ERROR_MESSAGE);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Subscribes this wire adapter to future changes to the specified snapshot. Any changes
|
|
322
|
+
* to the snapshot will be automatically emitted to the component.
|
|
323
|
+
*
|
|
324
|
+
* @param snapshot Snapshot
|
|
325
|
+
* @param subscriptionCallback callback
|
|
326
|
+
*/
|
|
327
|
+
subscribe(snapshot) {
|
|
328
|
+
// always clean up any old subscription that we might have
|
|
329
|
+
this.unsubscribe();
|
|
330
|
+
// but only subscribe if component is currently connected
|
|
331
|
+
if (this.connected) {
|
|
332
|
+
this.unsubscriber = this.luvio.storeSubscribe(snapshot, this.emit.bind(this));
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Deletes this wire adapter's snapshot subscription (if any).
|
|
337
|
+
*/
|
|
338
|
+
unsubscribe() {
|
|
339
|
+
// clean up subscription
|
|
340
|
+
if (this.unsubscriber !== undefined) {
|
|
341
|
+
this.unsubscriber();
|
|
342
|
+
this.unsubscriber = undefined;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Wraps a luvio Adapter in a WireAdapterConstructor that conforms to https://rfcs.lwc.dev/rfcs/lwc/0000-wire-reform#wire-adapter-protocol.
|
|
348
|
+
*
|
|
349
|
+
* @param adapter Adapter
|
|
350
|
+
* @param name name to assign to the generated constructor
|
|
351
|
+
* @param luvio Luvio
|
|
352
|
+
*/
|
|
353
|
+
function createWireAdapterConstructor$1(adapter, name, luvio) {
|
|
354
|
+
const constructor = function (callback) {
|
|
355
|
+
const delegate = new LWCLuvioWireAdapter(adapter, name, luvio, callback);
|
|
356
|
+
this.connect = () => delegate.connect();
|
|
357
|
+
this.disconnect = () => delegate.disconnect();
|
|
358
|
+
this.update = (config, context) => delegate.update(config, context);
|
|
359
|
+
};
|
|
360
|
+
Object.defineProperty(constructor, 'name', { value: name });
|
|
361
|
+
return constructor;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
class LWCInfinteScrollingLuvioWireAdapter extends LWCLuvioWireAdapter {
|
|
365
|
+
/**
|
|
366
|
+
* Called when the component associated with the wire adapter is connected.
|
|
367
|
+
*/
|
|
368
|
+
connect() {
|
|
369
|
+
this.connectTimestamp = Date.now();
|
|
370
|
+
super.connect();
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Called when the component associated with the wire adapter is disconnected.
|
|
374
|
+
*/
|
|
375
|
+
disconnect() {
|
|
376
|
+
this.connectTimestamp = undefined;
|
|
377
|
+
super.disconnect();
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Called when new or updated config is supplied to the wire adapter.
|
|
381
|
+
*
|
|
382
|
+
* @param config new config parameters for the wire adapter
|
|
383
|
+
* @param context context for the wire adapter
|
|
384
|
+
*/
|
|
385
|
+
update(config, context) {
|
|
386
|
+
if (this.connectTimestamp) {
|
|
387
|
+
const mergedContext = Object.assign({
|
|
388
|
+
cachePolicy: {
|
|
389
|
+
type: 'valid-at',
|
|
390
|
+
timestamp: this.connectTimestamp,
|
|
391
|
+
},
|
|
392
|
+
}, context);
|
|
393
|
+
super.unsubscribe();
|
|
394
|
+
this.config = sanitize(config);
|
|
395
|
+
this.callAdapterWithContext(mergedContext);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
super.update(config, context);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Calls the adapter if config has been set and the component is connected.
|
|
403
|
+
*/
|
|
404
|
+
callAdapterWithContext(context) {
|
|
405
|
+
if (!this.connected || this.config === undefined) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const snapshotOrPromise = this.adapter(this.config, context);
|
|
409
|
+
super.processAdapterResponse(snapshotOrPromise);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function createInfiniteScrollingWireAdapterConstructor$1(adapter, name, luvio) {
|
|
413
|
+
const constructor = function (callback) {
|
|
414
|
+
const delegate = new LWCInfinteScrollingLuvioWireAdapter(adapter, name, luvio, callback);
|
|
415
|
+
this.connect = () => delegate.connect();
|
|
416
|
+
this.disconnect = () => delegate.disconnect();
|
|
417
|
+
this.update = (config, context) => delegate.update(config, context);
|
|
418
|
+
};
|
|
419
|
+
Object.defineProperty(constructor, 'name', { value: name });
|
|
420
|
+
return constructor;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function snapshotToPayload(snapshot) {
|
|
424
|
+
const payload = {
|
|
425
|
+
data: undefined,
|
|
426
|
+
errors: undefined,
|
|
427
|
+
};
|
|
428
|
+
if (snapshot === undefined) {
|
|
429
|
+
return payload;
|
|
430
|
+
}
|
|
431
|
+
payload.data = extractSnapshotData(snapshot);
|
|
432
|
+
// TODO handle batch error scenarios.
|
|
433
|
+
if ('error' in snapshot && snapshot.error !== undefined) {
|
|
434
|
+
if (Array.isArray(snapshot.error)) {
|
|
435
|
+
payload.errors = snapshot.error;
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
payload.errors = [snapshot.error];
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return payload;
|
|
442
|
+
}
|
|
443
|
+
class LWCGraphQLLuvioWireAdapter extends LWCLuvioWireAdapter {
|
|
444
|
+
constructor(adapter, name, luvio, astResolver, callback) {
|
|
445
|
+
super(adapter, name, luvio, callback);
|
|
446
|
+
this.astResolver = astResolver;
|
|
447
|
+
}
|
|
448
|
+
update(config, _context) {
|
|
449
|
+
this.unsubscribe();
|
|
450
|
+
if (config.batchQuery) {
|
|
451
|
+
this.config = {
|
|
452
|
+
batchQuery: config.batchQuery.map((individualConfig) => safeSanitizeGraphQLConfigObject(individualConfig)),
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
this.config = safeSanitizeGraphQLConfigObject(config);
|
|
457
|
+
}
|
|
458
|
+
this.callAdapter();
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Emits new values to the callback.
|
|
462
|
+
*
|
|
463
|
+
* @param snapshot Snapshot to be emitted, if omitted then undefineds will be emitted
|
|
464
|
+
*/
|
|
465
|
+
emit(snapshot) {
|
|
466
|
+
const payload = snapshotToPayload(snapshot);
|
|
467
|
+
dataToTupleWeakMap.set(payload, [this.name, snapshot]);
|
|
468
|
+
try {
|
|
469
|
+
this.callback(payload);
|
|
470
|
+
}
|
|
471
|
+
catch (error) {
|
|
472
|
+
if (error instanceof Error) {
|
|
473
|
+
throwAnnotatedError(error, USERLAND_PROVISION_ERROR_MESSAGE);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Coerce config before calling the adapter, preserve current behavior otherwise
|
|
479
|
+
*/
|
|
480
|
+
callAdapter() {
|
|
481
|
+
if (!this.connected || this.config === undefined) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
const config = this.config;
|
|
485
|
+
if ('batchQuery' in config) {
|
|
486
|
+
const batchConfig = {
|
|
487
|
+
batchQuery: config.batchQuery.map((individualConfig) => this.resolveQueryAst(individualConfig)),
|
|
488
|
+
};
|
|
489
|
+
// If any of the configurations are invalid, we bail out of calling the adapter.
|
|
490
|
+
if (batchConfig.batchQuery.some((val) => val === undefined)) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
const snapshotOrPromise = this.adapter(batchConfig);
|
|
494
|
+
this.processAdapterResponse(snapshotOrPromise);
|
|
495
|
+
}
|
|
496
|
+
else if ('query' in config) {
|
|
497
|
+
const singleConfig = this.resolveQueryAst(config);
|
|
498
|
+
if (singleConfig !== undefined) {
|
|
499
|
+
const snapshotOrPromise = this.adapter(singleConfig);
|
|
500
|
+
this.processAdapterResponse(snapshotOrPromise);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
resolveQueryAst(config) {
|
|
505
|
+
if (config.query === null) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const ast = this.astResolver(config.query);
|
|
509
|
+
if (ast === undefined && config.query !== undefined) {
|
|
510
|
+
// this should only happen if the user didn't parse the query
|
|
511
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
512
|
+
throw new Error(USERLAND_GRAPHQL_PARSER_ERROR_MESSAGE);
|
|
513
|
+
}
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
const resolvedAdapterConfig = {
|
|
517
|
+
...config,
|
|
518
|
+
query: ast,
|
|
519
|
+
};
|
|
520
|
+
return resolvedAdapterConfig;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
function extractSnapshotData(snapshot) {
|
|
524
|
+
if ('data' in snapshot && snapshot.data !== undefined) {
|
|
525
|
+
const isSingleGraphQLData = 'data' in snapshot.data && snapshot.data.data !== undefined;
|
|
526
|
+
const isBatchGraphQLData = 'results' in snapshot.data && snapshot.data.results !== undefined;
|
|
527
|
+
if (isSingleGraphQLData)
|
|
528
|
+
return snapshot.data.data;
|
|
529
|
+
if (isBatchGraphQLData)
|
|
530
|
+
return snapshot.data;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Wraps a luvio Adapter in a WireAdapterConstructor that conforms to https://rfcs.lwc.dev/rfcs/lwc/0000-wire-reform#wire-adapter-protocol.
|
|
535
|
+
*
|
|
536
|
+
* @param adapter Adapter
|
|
537
|
+
* @param name name to assign to the generated constructor
|
|
538
|
+
* @param luvio Luvio
|
|
539
|
+
*/
|
|
540
|
+
function createGraphQLWireAdapterConstructor$1(adapter, name, luvio, astResolver) {
|
|
541
|
+
const constructor = function (callback) {
|
|
542
|
+
const delegate = new LWCGraphQLLuvioWireAdapter(adapter, name, luvio, astResolver, callback);
|
|
543
|
+
this.connect = () => delegate.connect();
|
|
544
|
+
this.disconnect = () => delegate.disconnect();
|
|
545
|
+
this.update = (config, context) => delegate.update(config, context);
|
|
546
|
+
};
|
|
547
|
+
Object.defineProperty(constructor, 'name', { value: name });
|
|
548
|
+
return constructor;
|
|
549
|
+
}
|
|
550
|
+
function safeSanitizeGraphQLConfigObject(config) {
|
|
551
|
+
// graphql query AST is passed by reference
|
|
552
|
+
// sanitizing it makes a copy and we lose that reference
|
|
553
|
+
// so we avoid sanitizing it
|
|
554
|
+
return {
|
|
555
|
+
...sanitize(config),
|
|
556
|
+
query: config.query,
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// For use by callers within this module to instrument interesting things.
|
|
561
|
+
let instrumentation = {
|
|
562
|
+
refreshCalled: (_fromSource) => { },
|
|
563
|
+
instrumentAdapter: (adapter, _metadata) => {
|
|
564
|
+
return adapter;
|
|
565
|
+
},
|
|
566
|
+
};
|
|
567
|
+
/**
|
|
568
|
+
* Allows external modules (typically a runtime environment) to set
|
|
569
|
+
* instrumentation hooks for this module. Note that the hooks are
|
|
570
|
+
* incremental - hooks not suppiled in newInstrumentation will retain
|
|
571
|
+
* their previous values. The default instrumentation hooks are no-ops.
|
|
572
|
+
*
|
|
573
|
+
* @param newInstrumentation instrumentation hooks to be overridden
|
|
574
|
+
*/
|
|
575
|
+
function instrument(newInstrumentation) {
|
|
576
|
+
instrumentation = Object.assign(instrumentation, newInstrumentation);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
let refresh;
|
|
580
|
+
function bindWireRefresh(luvio) {
|
|
581
|
+
const wireRefresh = bindWireRefresh$1(luvio);
|
|
582
|
+
refresh = (data, apiFamily) => {
|
|
583
|
+
instrumentation.refreshCalled(apiFamily);
|
|
584
|
+
return wireRefresh(data);
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
function createInstrumentedAdapter(adapter, metadata) {
|
|
589
|
+
return instrumentation.instrumentAdapter(adapter, metadata);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
function createLDSAdapter(luvio, name, factory) {
|
|
593
|
+
return factory(luvio);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const { create, defineProperty, defineProperties } = Object;
|
|
597
|
+
|
|
598
|
+
var SnapshotState;
|
|
599
|
+
(function (SnapshotState) {
|
|
600
|
+
SnapshotState["Fulfilled"] = "Fulfilled";
|
|
601
|
+
SnapshotState["Unfulfilled"] = "Unfulfilled";
|
|
602
|
+
SnapshotState["Error"] = "Error";
|
|
603
|
+
SnapshotState["Pending"] = "Pending";
|
|
604
|
+
SnapshotState["Stale"] = "Stale";
|
|
605
|
+
})(SnapshotState || (SnapshotState = {}));
|
|
606
|
+
function isErrorSnapshot(snapshot) {
|
|
607
|
+
return snapshot.state === SnapshotState.Error;
|
|
608
|
+
}
|
|
609
|
+
function isPendingSnapshot(snapshot) {
|
|
610
|
+
return snapshot.state === SnapshotState.Pending;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
function isPromise(value) {
|
|
614
|
+
// check for Thenable due to test frameworks using custom Promise impls
|
|
615
|
+
return value !== null && value.then !== undefined;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function snapshotToTuple$1(snapshot) {
|
|
619
|
+
if (isErrorSnapshot(snapshot)) {
|
|
620
|
+
return {
|
|
621
|
+
data: undefined,
|
|
622
|
+
error: snapshot.error,
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
// We might still get pending snapshot here from invoke calls here
|
|
626
|
+
return {
|
|
627
|
+
data: snapshot.data,
|
|
628
|
+
error: undefined,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
function createInvalidConfigError$1() {
|
|
632
|
+
return {
|
|
633
|
+
data: undefined,
|
|
634
|
+
error: {
|
|
635
|
+
ok: false,
|
|
636
|
+
status: 400,
|
|
637
|
+
statusText: 'INVALID_CONFIG',
|
|
638
|
+
body: undefined,
|
|
639
|
+
headers: {},
|
|
640
|
+
errorType: 'fetchResponse',
|
|
641
|
+
},
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Creates an imperative adapter
|
|
646
|
+
*
|
|
647
|
+
* @param luvio Luvio
|
|
648
|
+
* @param adapter luvio adapter
|
|
649
|
+
* @param metadata AdapterMetadata
|
|
650
|
+
* @returns Imperative adapter object with invoke and subscribe functions
|
|
651
|
+
*/
|
|
652
|
+
function createImperativeAdapter(luvio, adapter, metadata) {
|
|
653
|
+
const { name } = metadata;
|
|
654
|
+
const imperativeAdapterInvoke = (config, requestContext, callback) => {
|
|
655
|
+
const snapshotOrPromise = adapter(config, requestContext);
|
|
656
|
+
if (snapshotOrPromise === null) {
|
|
657
|
+
callback(createInvalidConfigError$1());
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
if (!isPromise(snapshotOrPromise)) {
|
|
661
|
+
callback(snapshotToTuple$1(snapshotOrPromise));
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
snapshotOrPromise.then((snapshot) => {
|
|
665
|
+
if (snapshot === null) {
|
|
666
|
+
callback(createInvalidConfigError$1());
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
callback(snapshotToTuple$1(snapshot));
|
|
670
|
+
});
|
|
671
|
+
};
|
|
672
|
+
defineProperty(imperativeAdapterInvoke, 'name', {
|
|
673
|
+
value: `${name}_invoke`,
|
|
674
|
+
});
|
|
675
|
+
// Invokes the adapter and subscribes to the received snapshot
|
|
676
|
+
// Returns an unsubscribe function to the consumer
|
|
677
|
+
const imperativeAdapterSubscribe = (config, requestContext, callback) => {
|
|
678
|
+
let subscriberCallback = callback;
|
|
679
|
+
let unsub;
|
|
680
|
+
const snapshotOrPromise = adapter(config, requestContext);
|
|
681
|
+
if (snapshotOrPromise === null) {
|
|
682
|
+
subscriberCallback(createInvalidConfigError$1());
|
|
683
|
+
return () => { };
|
|
684
|
+
}
|
|
685
|
+
// Can rebuild lead to pending snapshots?
|
|
686
|
+
const luvioStoreSubscribe = (snapshot) => {
|
|
687
|
+
unsub = luvio.storeSubscribe(snapshot, (snapshotFromRebuild) => {
|
|
688
|
+
if (subscriberCallback !== null && !isPendingSnapshot(snapshotFromRebuild)) {
|
|
689
|
+
subscriberCallback(snapshotToTuple$1(snapshotFromRebuild));
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
};
|
|
693
|
+
if (!isPromise(snapshotOrPromise)) {
|
|
694
|
+
// We don't want to return pending snapshots to user-land
|
|
695
|
+
// Instead we just subscribe to it
|
|
696
|
+
if (!isPendingSnapshot(snapshotOrPromise)) {
|
|
697
|
+
subscriberCallback(snapshotToTuple$1(snapshotOrPromise));
|
|
698
|
+
}
|
|
699
|
+
luvioStoreSubscribe(snapshotOrPromise);
|
|
700
|
+
}
|
|
701
|
+
else {
|
|
702
|
+
snapshotOrPromise.then((snapshot) => {
|
|
703
|
+
if (subscriberCallback !== null) {
|
|
704
|
+
if (snapshot === null) {
|
|
705
|
+
subscriberCallback(createInvalidConfigError$1());
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
// We don't want to return pending snapshots to user-land
|
|
709
|
+
// Instead we just subscribe to it
|
|
710
|
+
if (!isPendingSnapshot(snapshot)) {
|
|
711
|
+
subscriberCallback(snapshotToTuple$1(snapshot));
|
|
712
|
+
}
|
|
713
|
+
luvioStoreSubscribe(snapshot);
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
return () => {
|
|
718
|
+
if (subscriberCallback !== null && unsub !== undefined) {
|
|
719
|
+
unsub();
|
|
720
|
+
}
|
|
721
|
+
subscriberCallback = null;
|
|
722
|
+
unsub = undefined;
|
|
723
|
+
};
|
|
724
|
+
};
|
|
725
|
+
defineProperty(imperativeAdapterSubscribe, 'name', {
|
|
726
|
+
value: `${name}_subscribe`,
|
|
727
|
+
});
|
|
728
|
+
return {
|
|
729
|
+
invoke: imperativeAdapterInvoke,
|
|
730
|
+
subscribe: imperativeAdapterSubscribe,
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function snapshotToTuple(snapshot) {
|
|
735
|
+
if (isErrorSnapshot(snapshot)) {
|
|
736
|
+
if (snapshot.error.errorType === 'adapterError') {
|
|
737
|
+
// GraphQL can return 200 with an errors array
|
|
738
|
+
return {
|
|
739
|
+
data: undefined,
|
|
740
|
+
errors: snapshot.error.error,
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
// This is a network error or some other error - usually with a single error bubled up.
|
|
745
|
+
return {
|
|
746
|
+
data: undefined,
|
|
747
|
+
errors: [snapshot.error],
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
// cast any PendingSnapshot to FulfilledSnapshot here,
|
|
752
|
+
// we shouldn't get anything pending at this point
|
|
753
|
+
const payload = {};
|
|
754
|
+
const dataSnapshot = snapshot;
|
|
755
|
+
if ('data' in dataSnapshot.data && dataSnapshot.data.data !== undefined) {
|
|
756
|
+
payload.data = dataSnapshot.data.data;
|
|
757
|
+
}
|
|
758
|
+
if (dataSnapshot.data.errors !== undefined) {
|
|
759
|
+
payload.errors = dataSnapshot.data.errors;
|
|
760
|
+
}
|
|
761
|
+
return payload;
|
|
762
|
+
}
|
|
763
|
+
function createInvalidConfigError() {
|
|
764
|
+
return {
|
|
765
|
+
data: undefined,
|
|
766
|
+
errors: [
|
|
767
|
+
{
|
|
768
|
+
ok: false,
|
|
769
|
+
status: 400,
|
|
770
|
+
statusText: 'INVALID_CONFIG',
|
|
771
|
+
body: undefined,
|
|
772
|
+
headers: {},
|
|
773
|
+
errorType: 'fetchResponse',
|
|
774
|
+
},
|
|
775
|
+
],
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Creates an imperative adapter
|
|
780
|
+
*
|
|
781
|
+
* @param luvio Luvio
|
|
782
|
+
* @param adapter luvio adapter
|
|
783
|
+
* @param metadata AdapterMetadata
|
|
784
|
+
* @returns Imperative adapter object with invoke and subscribe functions
|
|
785
|
+
*/
|
|
786
|
+
function createGraphQLImperativeAdapter(luvio, adapter, metadata, astResolver) {
|
|
787
|
+
const { name } = metadata;
|
|
788
|
+
const imperativeAdapterInvoke = (config, requestContext, callback) => {
|
|
789
|
+
let coercedConfig = null;
|
|
790
|
+
if ('batchQuery' in config) {
|
|
791
|
+
coercedConfig = {
|
|
792
|
+
batchQuery: config.batchQuery.map((individualConfig) => ({
|
|
793
|
+
...individualConfig,
|
|
794
|
+
query: astResolver(individualConfig.query),
|
|
795
|
+
})),
|
|
796
|
+
};
|
|
797
|
+
// If any of the configurations are invalid, we bail out of calling the adapter.
|
|
798
|
+
if (coercedConfig.batchQuery.some((individualConfig) => individualConfig.query === undefined)) {
|
|
799
|
+
callback(createInvalidConfigError());
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
else if ('query' in config) {
|
|
804
|
+
const ast = astResolver(config.query);
|
|
805
|
+
if (ast === undefined) {
|
|
806
|
+
callback(createInvalidConfigError());
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
coercedConfig = {
|
|
810
|
+
...config,
|
|
811
|
+
query: ast,
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
const snapshotOrPromise = adapter(coercedConfig, requestContext);
|
|
815
|
+
if (snapshotOrPromise === null) {
|
|
816
|
+
callback(createInvalidConfigError());
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
if (!isPromise(snapshotOrPromise)) {
|
|
820
|
+
callback(snapshotToTuple(snapshotOrPromise));
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
snapshotOrPromise.then((snapshot) => {
|
|
824
|
+
if (snapshot === null) {
|
|
825
|
+
callback(createInvalidConfigError());
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
callback(snapshotToTuple(snapshot));
|
|
829
|
+
});
|
|
830
|
+
};
|
|
831
|
+
defineProperty(imperativeAdapterInvoke, 'name', {
|
|
832
|
+
value: `${name}_invoke`,
|
|
833
|
+
});
|
|
834
|
+
// Invokes the adapter and subscribes to the received snapshot
|
|
835
|
+
// Returns an unsubscribe function to the consumer
|
|
836
|
+
const imperativeAdapterSubscribe = (config, requestContext, callback) => {
|
|
837
|
+
let subscriberCallback = callback;
|
|
838
|
+
let unsub;
|
|
839
|
+
let coercedConfig = null;
|
|
840
|
+
if ('batchQuery' in config) {
|
|
841
|
+
coercedConfig = {
|
|
842
|
+
batchQuery: config.batchQuery.map((individualConfig) => ({
|
|
843
|
+
...individualConfig,
|
|
844
|
+
query: astResolver(individualConfig.query),
|
|
845
|
+
})),
|
|
846
|
+
};
|
|
847
|
+
// If any of the configurations are invalid, we bail out of calling the adapter.
|
|
848
|
+
if (coercedConfig.batchQuery.some((individualConfig) => individualConfig.query === undefined)) {
|
|
849
|
+
callback(createInvalidConfigError());
|
|
850
|
+
return () => { };
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
else if ('query' in config) {
|
|
854
|
+
const ast = astResolver(config.query);
|
|
855
|
+
if (ast === undefined) {
|
|
856
|
+
callback(createInvalidConfigError());
|
|
857
|
+
return () => { };
|
|
858
|
+
}
|
|
859
|
+
coercedConfig = {
|
|
860
|
+
...config,
|
|
861
|
+
query: ast,
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
const snapshotOrPromise = adapter(coercedConfig, requestContext);
|
|
865
|
+
if (snapshotOrPromise === null) {
|
|
866
|
+
subscriberCallback(createInvalidConfigError());
|
|
867
|
+
return () => { };
|
|
868
|
+
}
|
|
869
|
+
// Can rebuild lead to pending snapshots?
|
|
870
|
+
const luvioStoreSubscribe = (snapshot) => {
|
|
871
|
+
unsub = luvio.storeSubscribe(snapshot, (snapshotFromRebuild) => {
|
|
872
|
+
if (subscriberCallback !== null && !isPendingSnapshot(snapshotFromRebuild)) {
|
|
873
|
+
subscriberCallback(snapshotToTuple(snapshotFromRebuild));
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
};
|
|
877
|
+
if (!isPromise(snapshotOrPromise)) {
|
|
878
|
+
// We don't want to return pending snapshots to user-land
|
|
879
|
+
// Instead we just subscribe to it
|
|
880
|
+
if (!isPendingSnapshot(snapshotOrPromise)) {
|
|
881
|
+
subscriberCallback(snapshotToTuple(snapshotOrPromise));
|
|
882
|
+
}
|
|
883
|
+
luvioStoreSubscribe(snapshotOrPromise);
|
|
884
|
+
}
|
|
885
|
+
else {
|
|
886
|
+
snapshotOrPromise.then((snapshot) => {
|
|
887
|
+
if (subscriberCallback !== null) {
|
|
888
|
+
if (snapshot === null) {
|
|
889
|
+
subscriberCallback(createInvalidConfigError());
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
// TODO [W-11370904]: revisit this. Does GraphQL need to worry about pending?
|
|
893
|
+
// We don't want to return pending snapshots to user-land
|
|
894
|
+
// Instead we just subscribe to it
|
|
895
|
+
if (!isPendingSnapshot(snapshot)) {
|
|
896
|
+
subscriberCallback(snapshotToTuple(snapshot));
|
|
897
|
+
}
|
|
898
|
+
luvioStoreSubscribe(snapshot);
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
return () => {
|
|
903
|
+
if (subscriberCallback !== null && unsub !== undefined) {
|
|
904
|
+
unsub();
|
|
905
|
+
}
|
|
906
|
+
subscriberCallback = null;
|
|
907
|
+
unsub = undefined;
|
|
908
|
+
};
|
|
909
|
+
};
|
|
910
|
+
defineProperty(imperativeAdapterSubscribe, 'name', {
|
|
911
|
+
value: `${name}_subscribe`,
|
|
912
|
+
});
|
|
913
|
+
return {
|
|
914
|
+
invoke: imperativeAdapterInvoke,
|
|
915
|
+
subscribe: imperativeAdapterSubscribe,
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function createWireAdapterConstructor(luvio, adapter, metadata) {
|
|
920
|
+
const { apiFamily, name } = metadata;
|
|
921
|
+
return createWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio);
|
|
922
|
+
}
|
|
923
|
+
function createInfiniteScrollingWireAdapterConstructor(luvio, adapter, metadata) {
|
|
924
|
+
const { apiFamily, name } = metadata;
|
|
925
|
+
return createInfiniteScrollingWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio);
|
|
926
|
+
}
|
|
927
|
+
function createGraphQLWireAdapterConstructor(luvio, adapter, metadata, astResolver) {
|
|
928
|
+
const { apiFamily, name } = metadata;
|
|
929
|
+
return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
export { ADAPTER_UNFULFILLED_ERROR, REFRESH_ADAPTER_EVENT, bindWireRefresh, createGraphQLImperativeAdapter, createGraphQLWireAdapterConstructor, createImperativeAdapter, createInfiniteScrollingWireAdapterConstructor, createInstrumentedAdapter, createLDSAdapter, createWireAdapterConstructor, instrument, refresh };
|
|
933
|
+
// version: 0.131.0-5e4201fa2
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Luvio } from '@luvio/engine';
|
|
2
|
+
export type refreshApiNames = {
|
|
3
|
+
refreshApex: string;
|
|
4
|
+
refreshUiApi: string;
|
|
5
|
+
};
|
|
6
|
+
export declare let refresh: (data: any, apiFamily: keyof refreshApiNames) => Promise<undefined> | undefined;
|
|
7
|
+
export declare function bindWireRefresh(luvio: Luvio): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { REFRESH_ADAPTER_EVENT, ADAPTER_UNFULFILLED_ERROR } from '@luvio/lwc-luvio';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Adapter, AdapterRequestContext, ErrorResponse as LuvioErrorResponse, Luvio, Unsubscribe } from '@luvio/engine';
|
|
2
|
+
import type { AstResolver } from '@luvio/graphql-parser';
|
|
3
|
+
import type { GraphQLError, GraphQLInput } from '@luvio/lwc-luvio';
|
|
4
|
+
import type { AdapterMetadata } from './ldsAdapter';
|
|
5
|
+
interface DataResponse {
|
|
6
|
+
data: any;
|
|
7
|
+
errors?: GraphQLError[];
|
|
8
|
+
}
|
|
9
|
+
interface ErrorResponse {
|
|
10
|
+
data: undefined;
|
|
11
|
+
errors: LuvioErrorResponse[];
|
|
12
|
+
}
|
|
13
|
+
type DataCallbackTuple = DataResponse | ErrorResponse;
|
|
14
|
+
interface DataCallback {
|
|
15
|
+
(response: DataCallbackTuple): void;
|
|
16
|
+
}
|
|
17
|
+
type ImperativeAdapterInvokeType<C> = (config: C, context: AdapterRequestContext, callback: DataCallback) => void;
|
|
18
|
+
type ImperativeAdapterSubscribeType<C> = (config: C, context: AdapterRequestContext, callback: DataCallback) => Unsubscribe;
|
|
19
|
+
interface ImperativeAdapter<C> {
|
|
20
|
+
invoke: ImperativeAdapterInvokeType<C>;
|
|
21
|
+
subscribe: ImperativeAdapterSubscribeType<C>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates an imperative adapter
|
|
25
|
+
*
|
|
26
|
+
* @param luvio Luvio
|
|
27
|
+
* @param adapter luvio adapter
|
|
28
|
+
* @param metadata AdapterMetadata
|
|
29
|
+
* @returns Imperative adapter object with invoke and subscribe functions
|
|
30
|
+
*/
|
|
31
|
+
export declare function createGraphQLImperativeAdapter<C extends GraphQLInput, D>(luvio: Luvio, adapter: Adapter<C, D>, metadata: AdapterMetadata, astResolver: AstResolver): ImperativeAdapter<C>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Adapter, AdapterRequestContext, ErrorResponse as LuvioErrorResponse, Luvio, Snapshot, StaleSnapshot, UnfulfilledSnapshot, Unsubscribe } from '@luvio/engine';
|
|
2
|
+
import type { AdapterMetadata } from './ldsAdapter';
|
|
3
|
+
interface DataResponse<D> {
|
|
4
|
+
data: D;
|
|
5
|
+
error: undefined;
|
|
6
|
+
}
|
|
7
|
+
interface ErrorResponse {
|
|
8
|
+
data: undefined;
|
|
9
|
+
error: LuvioErrorResponse;
|
|
10
|
+
}
|
|
11
|
+
export type DataCallbackTuple<D> = DataResponse<D> | ErrorResponse;
|
|
12
|
+
export type CallbackSnapshot<D> = Exclude<Snapshot<D>, UnfulfilledSnapshot<D> | StaleSnapshot<D>>;
|
|
13
|
+
export interface DataCallback<D> {
|
|
14
|
+
(response: DataCallbackTuple<D>): void;
|
|
15
|
+
}
|
|
16
|
+
type ImperativeAdapterInvokeType<C, D> = (config: C, context: AdapterRequestContext | undefined, callback: DataCallback<D>) => void;
|
|
17
|
+
type ImperativeAdapterSubscribeType<C, D> = (config: C, context: AdapterRequestContext | undefined, callback: DataCallback<D>) => Unsubscribe;
|
|
18
|
+
export interface ImperativeAdapter<C, D> {
|
|
19
|
+
invoke: ImperativeAdapterInvokeType<C, D>;
|
|
20
|
+
subscribe: ImperativeAdapterSubscribeType<C, D>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates an imperative adapter
|
|
24
|
+
*
|
|
25
|
+
* @param luvio Luvio
|
|
26
|
+
* @param adapter luvio adapter
|
|
27
|
+
* @param metadata AdapterMetadata
|
|
28
|
+
* @returns Imperative adapter object with invoke and subscribe functions
|
|
29
|
+
*/
|
|
30
|
+
export declare function createImperativeAdapter<C, D>(luvio: Luvio, adapter: Adapter<C, D>, metadata: AdapterMetadata): ImperativeAdapter<C, D>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Adapter } from '@luvio/engine';
|
|
2
|
+
import type { AdapterMetadata } from './ldsAdapter';
|
|
3
|
+
import type { refreshApiNames } from './bindWireRefresh';
|
|
4
|
+
/**
|
|
5
|
+
* Instrumentation hooks exposed by this module.
|
|
6
|
+
*/
|
|
7
|
+
export interface LwcBindingsInstrumentation {
|
|
8
|
+
/**
|
|
9
|
+
* Called when an LWC calls `refresh`.
|
|
10
|
+
*/
|
|
11
|
+
refreshCalled?: (fromSource: keyof refreshApiNames) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Called when creating wire adapters.
|
|
14
|
+
*/
|
|
15
|
+
instrumentAdapter?: <C, D>(adapter: Adapter<C, D>, metadata: AdapterMetadata) => Adapter<C, D>;
|
|
16
|
+
}
|
|
17
|
+
export declare let instrumentation: {
|
|
18
|
+
refreshCalled: (_fromSource: keyof refreshApiNames) => void;
|
|
19
|
+
instrumentAdapter: <C, D>(adapter: Adapter<C, D>, _metadata: AdapterMetadata) => Adapter<C, D>;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Allows external modules (typically a runtime environment) to set
|
|
23
|
+
* instrumentation hooks for this module. Note that the hooks are
|
|
24
|
+
* incremental - hooks not suppiled in newInstrumentation will retain
|
|
25
|
+
* their previous values. The default instrumentation hooks are no-ops.
|
|
26
|
+
*
|
|
27
|
+
* @param newInstrumentation instrumentation hooks to be overridden
|
|
28
|
+
*/
|
|
29
|
+
export declare function instrument(newInstrumentation: LwcBindingsInstrumentation): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { bindWireRefresh, refresh } from './bindWireRefresh';
|
|
2
|
+
export { LwcBindingsInstrumentation, instrument } from './instrumentation';
|
|
3
|
+
export { createInstrumentedAdapter } from './instrumentedAdapter';
|
|
4
|
+
export { AdapterMetadata, createLDSAdapter } from './ldsAdapter';
|
|
5
|
+
export { createImperativeAdapter } from './imperativeAdapter';
|
|
6
|
+
export { createGraphQLImperativeAdapter } from './graphQLImperativeAdapter';
|
|
7
|
+
export { createWireAdapterConstructor, createInfiniteScrollingWireAdapterConstructor, createGraphQLWireAdapterConstructor, } from './wireAdapter';
|
|
8
|
+
export { DataCallback, DataCallbackTuple, ImperativeAdapter } from './imperativeAdapter';
|
|
9
|
+
export { REFRESH_ADAPTER_EVENT, ADAPTER_UNFULFILLED_ERROR } from './constants';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
declare const create: {
|
|
2
|
+
(o: object | null): any;
|
|
3
|
+
(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
|
|
4
|
+
}, defineProperty: <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T, defineProperties: <T>(o: T, properties: PropertyDescriptorMap & ThisType<any>) => T;
|
|
5
|
+
export { create as ObjectCreate, defineProperty as ObjectDefineProperty, defineProperties as ObjectDefineProperties, };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ErrorSnapshot, PendingSnapshot, Snapshot } from '@luvio/engine';
|
|
2
|
+
export declare function isErrorSnapshot(snapshot: Snapshot<unknown, unknown>): snapshot is ErrorSnapshot;
|
|
3
|
+
export declare function isPendingSnapshot<D>(snapshot: Snapshot<D, unknown>): snapshot is PendingSnapshot<D>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isPromise<D>(value: D | Promise<D> | null): value is Promise<D>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Adapter, Luvio } from '@luvio/engine';
|
|
2
|
+
import type { WireAdapterConstructor } from '@lwc/engine-core';
|
|
3
|
+
import type { AdapterMetadata } from './ldsAdapter';
|
|
4
|
+
import type { AstResolver } from '@luvio/graphql-parser';
|
|
5
|
+
export declare function createWireAdapterConstructor<C, D>(luvio: Luvio, adapter: Adapter<C, D>, metadata: AdapterMetadata): WireAdapterConstructor;
|
|
6
|
+
export declare function createInfiniteScrollingWireAdapterConstructor<C, D>(luvio: Luvio, adapter: Adapter<C, D>, metadata: AdapterMetadata): WireAdapterConstructor;
|
|
7
|
+
export declare function createGraphQLWireAdapterConstructor<C, D>(luvio: Luvio, adapter: Adapter<C, D>, metadata: AdapterMetadata, astResolver: AstResolver): WireAdapterConstructor;
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@salesforce/lds-bindings",
|
|
3
|
+
"version": "0.131.0",
|
|
4
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
|
+
"description": "LDS Bindings for SFDC",
|
|
6
|
+
"main": "dist/ldsBindings.js",
|
|
7
|
+
"module": "dist/ldsBindings.js",
|
|
8
|
+
"types": "dist/types/main.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/ldsBindings.js",
|
|
15
|
+
"types": "./dist/types/main.d.ts",
|
|
16
|
+
"default": "./dist/ldsBindings.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"sfdc": {
|
|
20
|
+
"path": "forcelds/ldsBindings/",
|
|
21
|
+
"overrides": {
|
|
22
|
+
"artifactDirectory": "dist"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"prepare": "yarn build",
|
|
27
|
+
"build": "rollup --config rollup.config.js",
|
|
28
|
+
"clean": "rm -rf dist",
|
|
29
|
+
"test:unit": "jest",
|
|
30
|
+
"test:unit:debug": "node --inspect-brk ../../node_modules/.bin/jest --runInBand",
|
|
31
|
+
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-bindings"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@salesforce/lds-graphql-parser": "1.131.0-244.6"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@lwc/engine-core": "2.41.1"
|
|
38
|
+
}
|
|
39
|
+
}
|