@devvit/ui-renderer 0.10.17-next-2024-02-23-065bf7067.0 → 0.10.17-next-2024-02-26-9e49b4eeb.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/client/app-ui-looper.d.ts +67 -0
- package/client/app-ui-looper.d.ts.map +1 -0
- package/client/app-ui-looper.js +206 -0
- package/client/app-ui-looper.test.d.ts.map +1 -0
- package/client/devvit-custom-post.d.ts +7 -1
- package/client/devvit-custom-post.d.ts.map +1 -1
- package/client/devvit-custom-post.js +88 -248
- package/client/ui-app.d.ts +18 -0
- package/client/ui-app.d.ts.map +1 -0
- package/client/ui-app.js +39 -0
- package/package.json +8 -8
- package/types/devvit-global.d.ts +5 -7
- package/types/devvit-global.d.ts.map +1 -1
- package/types/devvit-global.js +6 -8
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { BlockRenderEventType, Effect, LinkedBundle, Metadata, RenderPostRequest, RenderPostResponse, Struct, UIEvent } from '@devvit/protos';
|
|
2
|
+
import { ErrorCallback, LiteClient } from '@devvit/runtime-lite/client/BrowserLiteClient.js';
|
|
3
|
+
import { PluginCallback } from '@devvit/runtime-lite/runtime/RuntimeLite.js';
|
|
4
|
+
import { T3ID, TID } from '@devvit/shared-types/tid.js';
|
|
5
|
+
import { UIApp } from './ui-app.js';
|
|
6
|
+
type AppState = {
|
|
7
|
+
__postData?: {
|
|
8
|
+
thingId: TID | undefined;
|
|
9
|
+
config: Struct['fields'] | undefined;
|
|
10
|
+
};
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
};
|
|
13
|
+
type EventData = {
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* App render and effect looping logic. Rendering and event processing is as
|
|
18
|
+
* follows:
|
|
19
|
+
*
|
|
20
|
+
* 1. Try the local runtime, if available.
|
|
21
|
+
* 2. If a local runtime or bundle is unavailable, or local execution fails
|
|
22
|
+
* (including CircuitBreak), try the remote.
|
|
23
|
+
* 3. Report execution errors by callback only. In general, all errors are
|
|
24
|
+
* attempted to be tolerated.
|
|
25
|
+
*
|
|
26
|
+
* App / render state is always preserved even on error so a buggy app will try
|
|
27
|
+
* not to show any issues. A bundle or runtime can be replaced on the fly with
|
|
28
|
+
* losing state.
|
|
29
|
+
*/
|
|
30
|
+
export declare class AppUILooper {
|
|
31
|
+
#private;
|
|
32
|
+
meta?: Metadata | undefined;
|
|
33
|
+
onError?: ErrorCallback | undefined;
|
|
34
|
+
onPluginCall?: PluginCallback | undefined;
|
|
35
|
+
onRenderPost?: ((req: RenderPostRequest, rsp: RenderPostResponse) => void) | undefined;
|
|
36
|
+
onUserAction?: ((fx: Effect) => void) | undefined;
|
|
37
|
+
postConfig?: Struct['fields'] | undefined;
|
|
38
|
+
postID?: T3ID | undefined;
|
|
39
|
+
/** A client to the remote runtime. */
|
|
40
|
+
remote?: UIApp | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* A client to the local runtime.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
_local?: LiteClient | undefined;
|
|
46
|
+
/** Get the current app state with the current post state. */
|
|
47
|
+
get appState(): AppState;
|
|
48
|
+
/**
|
|
49
|
+
* Load an app bundle into the local runtime, if available. The bundle is
|
|
50
|
+
* assumed to implement a UIApp.
|
|
51
|
+
*/
|
|
52
|
+
load(app: Readonly<LinkedBundle>, sandbox: boolean): Promise<void>;
|
|
53
|
+
queueEvent(ev: UIEvent): void;
|
|
54
|
+
queueRenderPost(type: BlockRenderEventType, id: string | undefined, data: EventData): void;
|
|
55
|
+
get rendered(): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Discard app and render state. This is used indirectly by devvit-preview
|
|
58
|
+
* which frequently loads new bundles.
|
|
59
|
+
*/
|
|
60
|
+
resetAppState(): void;
|
|
61
|
+
/** Set the runtime source code. */
|
|
62
|
+
setLocalSrc(src: Blob | undefined): void;
|
|
63
|
+
/** Unload the app and reject any open requests. */
|
|
64
|
+
unload(): void;
|
|
65
|
+
}
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=app-ui-looper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-ui-looper.d.ts","sourceRoot":"","sources":["../../library/src/client/app-ui-looper.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,MAAM,EAGN,YAAY,EACZ,QAAQ,EAER,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,EACN,OAAO,EACR,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAEL,aAAa,EACb,UAAU,EACX,MAAM,kDAAkD,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAE7E,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,6BAA6B,CAAC;AAGxD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAQpC,KAAK,QAAQ,GAAG;IACd,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,GAAG,GAAG,SAAS,CAAC;QACzB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;KACtC,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AACF,KAAK,SAAS,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE5C;;;;;;;;;;;;;GAaG;AACH,qBAAa,WAAW;;IACtB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,YAAY,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAC1C,YAAY,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,kBAAkB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACvF,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAC1C,MAAM,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAC1B,sCAAsC;IACtC,MAAM,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAU3B;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAWhC,6DAA6D;IAC7D,IAAI,QAAQ,IAAI,QAAQ,CAGvB;IAED;;;OAGG;IACG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IASxE,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI;IAU7B,eAAe,CAAC,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAI1F,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;OAGG;IACH,aAAa,IAAI,IAAI;IAKrB,mCAAmC;IACnC,WAAW,CAAC,GAAG,EAAE,IAAI,GAAG,SAAS,GAAG,IAAI;IAUxC,mDAAmD;IACnD,MAAM,IAAI,IAAI;CAoGf"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _AppUILooper_instances, _AppUILooper_appState, _AppUILooper_q, _AppUILooper_rendered, _AppUILooper_rerenderTimeout, _AppUILooper_onEffects, _AppUILooper_onPluginCall, _AppUILooper_processEvent, _AppUILooper_renderPost;
|
|
13
|
+
import { BlockRenderEventType, RealtimeDefinition, } from '@devvit/protos';
|
|
14
|
+
import { BrowserLiteClient, } from '@devvit/runtime-lite/client/BrowserLiteClient.js';
|
|
15
|
+
import { isCircuitBreaker } from '@devvit/runtime-lite/types/CircuitBreaker.js';
|
|
16
|
+
import PQueue from 'p-queue';
|
|
17
|
+
import { initDevvitGlobal } from '../types/devvit-global.js';
|
|
18
|
+
// Effects that can only be fired as the result of a user action
|
|
19
|
+
const userActionEffects = ['showToast', 'showForm', 'navigateToUrl'];
|
|
20
|
+
initDevvitGlobal();
|
|
21
|
+
/**
|
|
22
|
+
* App render and effect looping logic. Rendering and event processing is as
|
|
23
|
+
* follows:
|
|
24
|
+
*
|
|
25
|
+
* 1. Try the local runtime, if available.
|
|
26
|
+
* 2. If a local runtime or bundle is unavailable, or local execution fails
|
|
27
|
+
* (including CircuitBreak), try the remote.
|
|
28
|
+
* 3. Report execution errors by callback only. In general, all errors are
|
|
29
|
+
* attempted to be tolerated.
|
|
30
|
+
*
|
|
31
|
+
* App / render state is always preserved even on error so a buggy app will try
|
|
32
|
+
* not to show any issues. A bundle or runtime can be replaced on the fly with
|
|
33
|
+
* losing state.
|
|
34
|
+
*/
|
|
35
|
+
export class AppUILooper {
|
|
36
|
+
constructor() {
|
|
37
|
+
_AppUILooper_instances.add(this);
|
|
38
|
+
/**
|
|
39
|
+
* App state is never reset in production. Prior remote executions may have
|
|
40
|
+
* occurred. The next loop will replace the state. Do not lose the current
|
|
41
|
+
* state even after a bundle has been downloaded and is ready to load. The
|
|
42
|
+
* only time state should be reinitialized is when a bundle has been
|
|
43
|
+
* _replaced_ such as by devvit-preview.
|
|
44
|
+
*/
|
|
45
|
+
_AppUILooper_appState.set(this, {});
|
|
46
|
+
/** No concurrency is used to enforce order. to-do: replace with array? */
|
|
47
|
+
_AppUILooper_q.set(this, new PQueue({ concurrency: 1 }));
|
|
48
|
+
/**
|
|
49
|
+
* True if app has rendered since loaded. Since a successful render isn't
|
|
50
|
+
* known at queue time, it's possible for multiple redundant renders to be
|
|
51
|
+
* enqueued.
|
|
52
|
+
*/
|
|
53
|
+
_AppUILooper_rendered.set(this, false);
|
|
54
|
+
_AppUILooper_rerenderTimeout.set(this, void 0);
|
|
55
|
+
_AppUILooper_onPluginCall.set(this, (id, serviceName, method, args, meta) => {
|
|
56
|
+
this.onPluginCall?.(id, serviceName, method, args, meta);
|
|
57
|
+
if (serviceName === RealtimeDefinition.fullName &&
|
|
58
|
+
method === RealtimeDefinition.methods.send.name)
|
|
59
|
+
this._local?.onPluginResponse(id, { error: undefined, success: true, value: {} });
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/** Get the current app state with the current post state. */
|
|
63
|
+
get appState() {
|
|
64
|
+
__classPrivateFieldGet(this, _AppUILooper_appState, "f").__postData = { thingId: this.postID, config: this.postConfig };
|
|
65
|
+
return __classPrivateFieldGet(this, _AppUILooper_appState, "f");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Load an app bundle into the local runtime, if available. The bundle is
|
|
69
|
+
* assumed to implement a UIApp.
|
|
70
|
+
*/
|
|
71
|
+
async load(app, sandbox) {
|
|
72
|
+
this.unload();
|
|
73
|
+
try {
|
|
74
|
+
await this._local?.loadBundle(app, sandbox);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
this.onError?.('Error', err);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
queueEvent(ev) {
|
|
81
|
+
if (ev.queue) {
|
|
82
|
+
// TODO: Add QoS for different types of events on alternate queues. For
|
|
83
|
+
// now, treat alternate queues as having infinite concurrency.
|
|
84
|
+
void __classPrivateFieldGet(this, _AppUILooper_instances, "m", _AppUILooper_processEvent).call(this, ev);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
void __classPrivateFieldGet(this, _AppUILooper_q, "f").add(() => __classPrivateFieldGet(this, _AppUILooper_instances, "m", _AppUILooper_processEvent).call(this, ev));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
queueRenderPost(type, id, data) {
|
|
91
|
+
void __classPrivateFieldGet(this, _AppUILooper_q, "f").add(() => __classPrivateFieldGet(this, _AppUILooper_instances, "m", _AppUILooper_renderPost).call(this, type, id, data));
|
|
92
|
+
}
|
|
93
|
+
get rendered() {
|
|
94
|
+
return __classPrivateFieldGet(this, _AppUILooper_rendered, "f");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Discard app and render state. This is used indirectly by devvit-preview
|
|
98
|
+
* which frequently loads new bundles.
|
|
99
|
+
*/
|
|
100
|
+
resetAppState() {
|
|
101
|
+
__classPrivateFieldSet(this, _AppUILooper_rendered, false, "f");
|
|
102
|
+
__classPrivateFieldSet(this, _AppUILooper_appState, {}, "f");
|
|
103
|
+
}
|
|
104
|
+
/** Set the runtime source code. */
|
|
105
|
+
setLocalSrc(src) {
|
|
106
|
+
this.unload();
|
|
107
|
+
this._local = src
|
|
108
|
+
? new BrowserLiteClient(src, (type, err) => this.onError?.(type, err), {
|
|
109
|
+
callback: __classPrivateFieldGet(this, _AppUILooper_onPluginCall, "f"),
|
|
110
|
+
plugins: [RealtimeDefinition.fullName],
|
|
111
|
+
})
|
|
112
|
+
: undefined;
|
|
113
|
+
}
|
|
114
|
+
/** Unload the app and reject any open requests. */
|
|
115
|
+
unload() {
|
|
116
|
+
if (__classPrivateFieldGet(this, _AppUILooper_rerenderTimeout, "f") != null)
|
|
117
|
+
clearTimeout(__classPrivateFieldGet(this, _AppUILooper_rerenderTimeout, "f"));
|
|
118
|
+
// Disable errors, wipe the old client rejecting any open promises, then
|
|
119
|
+
// re-enable errors. Leave app state as-is.
|
|
120
|
+
const onError = this.onError;
|
|
121
|
+
this.onError = undefined;
|
|
122
|
+
this._local?.quit();
|
|
123
|
+
this.onError = onError;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
_AppUILooper_appState = new WeakMap(), _AppUILooper_q = new WeakMap(), _AppUILooper_rendered = new WeakMap(), _AppUILooper_rerenderTimeout = new WeakMap(), _AppUILooper_onPluginCall = new WeakMap(), _AppUILooper_instances = new WeakSet(), _AppUILooper_onEffects = function _AppUILooper_onEffects(renderType, effects) {
|
|
127
|
+
for (const effect of effects) {
|
|
128
|
+
if (effect.rerenderUi) {
|
|
129
|
+
if (__classPrivateFieldGet(this, _AppUILooper_rerenderTimeout, "f") != null)
|
|
130
|
+
clearTimeout(__classPrivateFieldGet(this, _AppUILooper_rerenderTimeout, "f"));
|
|
131
|
+
__classPrivateFieldSet(this, _AppUILooper_rerenderTimeout, setTimeout(() => {
|
|
132
|
+
this.queueRenderPost(BlockRenderEventType.RENDER_EFFECT_EVENT, 'rerender-effect', {});
|
|
133
|
+
}, (effect.rerenderUi.delaySeconds ?? 0) * 1000), "f");
|
|
134
|
+
}
|
|
135
|
+
else if (effect.sendEvent?.event) {
|
|
136
|
+
this.queueEvent(effect.sendEvent.event);
|
|
137
|
+
}
|
|
138
|
+
else if (renderType !== BlockRenderEventType.RENDER_USER_ACTION ||
|
|
139
|
+
userActionEffects.some((type) => effect[type])) {
|
|
140
|
+
this.onUserAction?.(effect);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}, _AppUILooper_processEvent = async function _AppUILooper_processEvent(ev) {
|
|
144
|
+
let rsp;
|
|
145
|
+
const req = { event: ev, state: this.appState };
|
|
146
|
+
if (this._local?.ready) {
|
|
147
|
+
try {
|
|
148
|
+
rsp = (await this._local.call('HandleUIEvent', req, this.meta));
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
if (!isCircuitBreaker(err) || !this.remote)
|
|
152
|
+
this.onError?.('Error', err);
|
|
153
|
+
if (devvit?.logLocalErrors)
|
|
154
|
+
console.info('remote call', err);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!rsp) {
|
|
158
|
+
try {
|
|
159
|
+
rsp = await this.remote?.HandleUIEvent(req, this.meta);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
this.onError?.('Error', err);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (rsp) {
|
|
166
|
+
// Can only change state on the main queue.
|
|
167
|
+
if (!ev.queue) {
|
|
168
|
+
__classPrivateFieldSet(this, _AppUILooper_appState, rsp.state ?? {}, "f");
|
|
169
|
+
}
|
|
170
|
+
const renderType = ev.realtimeEvent
|
|
171
|
+
? BlockRenderEventType.RENDER_EFFECT_EVENT
|
|
172
|
+
: BlockRenderEventType.RENDER_USER_ACTION;
|
|
173
|
+
__classPrivateFieldGet(this, _AppUILooper_instances, "m", _AppUILooper_onEffects).call(this, renderType, rsp.effects);
|
|
174
|
+
}
|
|
175
|
+
}, _AppUILooper_renderPost = async function _AppUILooper_renderPost(type, id, data) {
|
|
176
|
+
const req = { blocks: { type, id, data }, state: this.appState };
|
|
177
|
+
let rsp;
|
|
178
|
+
if (this._local?.ready) {
|
|
179
|
+
try {
|
|
180
|
+
rsp = (await this._local?.call('RenderPost', req, this.meta));
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
if (isCircuitBreaker(err) && err.response)
|
|
184
|
+
rsp = err.response;
|
|
185
|
+
if (!isCircuitBreaker(err) || !this.remote)
|
|
186
|
+
this.onError?.('Error', err);
|
|
187
|
+
if (devvit?.logLocalErrors)
|
|
188
|
+
console.info('remote call', err);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (!rsp) {
|
|
192
|
+
try {
|
|
193
|
+
rsp = await this.remote?.RenderPost(req, this.meta);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
this.onError?.('Error', err);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (rsp) {
|
|
200
|
+
__classPrivateFieldSet(this, _AppUILooper_rendered, true, "f");
|
|
201
|
+
if (rsp.state)
|
|
202
|
+
__classPrivateFieldSet(this, _AppUILooper_appState, rsp.state, "f");
|
|
203
|
+
this.onRenderPost?.(req, rsp);
|
|
204
|
+
__classPrivateFieldGet(this, _AppUILooper_instances, "m", _AppUILooper_onEffects).call(this, req.blocks.type, rsp.effects);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-ui-looper.test.d.ts","sourceRoot":"","sources":["../../library/src/client/app-ui-looper.test.ts"],"names":[],"mappings":""}
|
|
@@ -5,6 +5,7 @@ import { WorkerErrorType } from '@devvit/runtime-lite/client/BrowserLiteClient.j
|
|
|
5
5
|
import type { ActorRef } from '@devvit/runtimes/common/runtime/ActorRef.js';
|
|
6
6
|
import { FaceplateEvent } from '@reddit/faceplate/event-types.js';
|
|
7
7
|
import { LitElement, PropertyValues } from 'lit';
|
|
8
|
+
import { UIApp } from './ui-app.js';
|
|
8
9
|
import '../blocks/components/devvit-blocks-renderer.js';
|
|
9
10
|
import '../blocks/components/devvit-blocks-webview.js';
|
|
10
11
|
import './devvit-animation-player.js';
|
|
@@ -49,12 +50,16 @@ export type DevvitUserActionEvent = FaceplateEvent<'devvit-user-action'> & {
|
|
|
49
50
|
*
|
|
50
51
|
* Assumes the loaded program is a CustomPost & UIEventHandler.
|
|
51
52
|
*
|
|
53
|
+
* The complexity of this class should only be the UI itself and proxying state
|
|
54
|
+
* to devvit-blocks-renderer and AppUILooper. Don't put logic here that you
|
|
55
|
+
* can't unit test.
|
|
56
|
+
*
|
|
52
57
|
* @slot - Loading / unloaded state.
|
|
53
58
|
*/
|
|
54
59
|
export declare class DevvitCustomPost extends LitElement {
|
|
55
60
|
#private;
|
|
56
61
|
/** Probably a wrapper around the remote runtime (compute-go). */
|
|
57
|
-
actorRef?: ActorRef | undefined;
|
|
62
|
+
actorRef?: ActorRef | UIApp | undefined;
|
|
58
63
|
bundle?: LinkedBundle | undefined;
|
|
59
64
|
localRuntimeCode?: Blob | undefined;
|
|
60
65
|
metadata?: Metadata | undefined;
|
|
@@ -68,6 +73,7 @@ export declare class DevvitCustomPost extends LitElement {
|
|
|
68
73
|
private _isSuspended;
|
|
69
74
|
private _rootBlock?;
|
|
70
75
|
constructor();
|
|
76
|
+
connectedCallback(): Promise<void>;
|
|
71
77
|
disconnectedCallback(): void;
|
|
72
78
|
get blocksConfig(): string;
|
|
73
79
|
rerender(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devvit-custom-post.d.ts","sourceRoot":"","sources":["../../library/src/client/devvit-custom-post.ts"],"names":[],"mappings":"AAAA,OAAO,kEAAkE,CAAC;AAE1E,OAAO,KAAK,EACV,WAAW,
|
|
1
|
+
{"version":3,"file":"devvit-custom-post.d.ts","sourceRoot":"","sources":["../../library/src/client/devvit-custom-post.ts"],"names":[],"mappings":"AAAA,OAAO,kEAAkE,CAAC;AAE1E,OAAO,KAAK,EACV,WAAW,EAEX,MAAM,EACN,YAAY,EACZ,QAAQ,EAER,kBAAkB,EAClB,MAAM,EACN,OAAO,EACR,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAKL,aAAa,EACd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAiB,eAAe,EAAE,MAAM,kDAAkD,CAAC;AAGlG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AAE5E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAElE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAiB,MAAM,KAAK,CAAC;AAOhE,OAAO,EAAa,KAAK,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,gDAAgD,CAAC;AACxD,OAAO,+CAA+C,CAAC;AACvD,OAAO,8BAA8B,CAAC;AAEtC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,oBAAoB,EAAE,gBAAgB,CAAC;KACxC;IACD,UAAU,mBAAmB;QAC3B,sBAAsB,EAAE,uBAAuB,CAAC;QAChD,kBAAkB,EAAE,mBAAmB,CAAC;QACxC,iBAAiB,EAAE,cAAc,CAAC,iBAAiB,CAAC,GAAG;YAAE,MAAM,EAAE,aAAa,CAAA;SAAE,CAAC;QACjF,oBAAoB,EAAE,qBAAqB,CAAC;KAC7C;CACF;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAC1D,MAAM,MAAM,uBAAuB,GAAG,cAAc,CAAC,sBAAsB,CAAC,GAAG;IAC7E,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AACF,MAAM,MAAM,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAAC;AAC/E,MAAM,MAAM,mBAAmB,GAAG,cAAc,CAAC,kBAAkB,CAAC,GAAG;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC;AAClG,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AACpE,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AACvD,MAAM,MAAM,qBAAqB,GAAG,cAAc,CAAC,oBAAoB,CAAC,GAAG;IACzE,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBACa,gBAAiB,SAAQ,UAAU;;IAC9C,iEAAiE;IACjC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IACxC,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAClC,gBAAgB,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAEzE,qBAAqB,EAAE,OAAO,CAAS;IAGgB,UAAU,EAAE,OAAO,CAAQ;IACzE,cAAc,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAExB,OAAO,CAAC,eAAe,CAAwB;IACvE,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAC,CAAoB;;IAcjC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxC,oBAAoB,IAAI,IAAI;IAMrC,IAAI,YAAY,IAAI,MAAM,CAGzB;IAGD,QAAQ,IAAI,IAAI;IAIhB,WAAoB,MAAM,8BAEzB;cAEkB,MAAM;cAoBA,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAuFhF"}
|
|
@@ -18,36 +18,33 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
18
18
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
19
19
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
20
20
|
};
|
|
21
|
-
var _DevvitCustomPost_instances,
|
|
21
|
+
var _DevvitCustomPost_instances, _DevvitCustomPost_lastRequest, _DevvitCustomPost_looper, _DevvitCustomPost_rootHeight, _DevvitCustomPost_bubble, _DevvitCustomPost_newRenderContext, _DevvitCustomPost_onError, _DevvitCustomPost_onPluginCall, _DevvitCustomPost_onRenderPost, _DevvitCustomPost_onUserActionEffect, _DevvitCustomPost_onUserActionEvent;
|
|
22
22
|
import '@reddit/faceplate-ui/templateRenderingStrategy/clientStrategy.js';
|
|
23
23
|
import { Block } from '@devvit/protos';
|
|
24
|
-
import { BlockConfig_Root, BlockRenderEventType, BlockStackDirection,
|
|
24
|
+
import { BlockConfig_Root, BlockRenderEventType, BlockStackDirection, RealtimeDefinition, } from '@devvit/protos';
|
|
25
25
|
import * as b64 from 'base64-js';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
26
|
+
import { isCircuitBreaker } from '@devvit/runtime-lite/types/CircuitBreaker.js';
|
|
27
|
+
import { asT3ID } from '@devvit/shared-types/tid.js';
|
|
28
28
|
import { customEvent } from '@reddit/faceplate/lib/custom-event.js';
|
|
29
|
-
import { LitElement, html } from 'lit';
|
|
29
|
+
import { LitElement, html, nothing } from 'lit';
|
|
30
30
|
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
31
|
-
import PQueue from 'p-queue';
|
|
32
31
|
import { DevvitBlocksRenderer } from '../blocks/components/devvit-blocks-renderer.js';
|
|
33
32
|
import { DEFAULT_ROOT_HEIGHT } from '../blocks/templates/renderBlock.js';
|
|
34
33
|
import { styles } from '../styles.js';
|
|
35
|
-
import {
|
|
34
|
+
import { AppUILooper } from './app-ui-looper.js';
|
|
35
|
+
import { RemoteApp } from './ui-app.js';
|
|
36
36
|
import '../blocks/components/devvit-blocks-renderer.js';
|
|
37
37
|
import '../blocks/components/devvit-blocks-webview.js';
|
|
38
38
|
import './devvit-animation-player.js';
|
|
39
|
-
initDevvitGlobal();
|
|
40
|
-
// Effects that can only be fired as the result of a user action
|
|
41
|
-
const USER_ACTION_EFFECTS = [
|
|
42
|
-
EffectType.EFFECT_SHOW_TOAST,
|
|
43
|
-
EffectType.EFFECT_SHOW_FORM,
|
|
44
|
-
EffectType.EFFECT_NAVIGATE_TO_URL,
|
|
45
|
-
];
|
|
46
39
|
/**
|
|
47
40
|
* Blocks program renderer.
|
|
48
41
|
*
|
|
49
42
|
* Assumes the loaded program is a CustomPost & UIEventHandler.
|
|
50
43
|
*
|
|
44
|
+
* The complexity of this class should only be the UI itself and proxying state
|
|
45
|
+
* to devvit-blocks-renderer and AppUILooper. Don't put logic here that you
|
|
46
|
+
* can't unit test.
|
|
47
|
+
*
|
|
51
48
|
* @slot - Loading / unloaded state.
|
|
52
49
|
*/
|
|
53
50
|
let DevvitCustomPost = class DevvitCustomPost extends LitElement {
|
|
@@ -58,53 +55,66 @@ let DevvitCustomPost = class DevvitCustomPost extends LitElement {
|
|
|
58
55
|
// to-do: don't use attributes initialized to true. They cannot be passed by
|
|
59
56
|
// attributes.
|
|
60
57
|
this.useSandbox = true;
|
|
61
|
-
_DevvitCustomPost_appState.set(this, {});
|
|
62
|
-
_DevvitCustomPost_customPostActor.set(this, void 0);
|
|
63
|
-
_DevvitCustomPost_hasInitialRender.set(this, false);
|
|
64
58
|
this._isSuspended = false; // eslint-disable-line @typescript-eslint/naming-convention
|
|
65
59
|
_DevvitCustomPost_lastRequest.set(this, void 0);
|
|
66
|
-
|
|
67
|
-
_DevvitCustomPost_rerenderTimeout.set(this, void 0);
|
|
60
|
+
_DevvitCustomPost_looper.set(this, new AppUILooper());
|
|
68
61
|
_DevvitCustomPost_rootHeight.set(this, void 0);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
_DevvitCustomPost_uiEventHandlerActor.set(this, void 0);
|
|
73
|
-
_DevvitCustomPost_handleUserAction.set(this, async (event) => {
|
|
74
|
-
await __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_userActionRender).call(this, event.detail.action.id, event.detail.action.data);
|
|
75
|
-
});
|
|
76
|
-
_DevvitCustomPost_makeRenderContext.set(this, () => ({
|
|
62
|
+
_DevvitCustomPost_newRenderContext.set(this, () => ({
|
|
63
|
+
experimental: this.useExperimentalBlocks,
|
|
64
|
+
onAction: (action) => __classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").queueRenderPost(BlockRenderEventType.RENDER_USER_ACTION, action.id, action.data ?? {}),
|
|
77
65
|
request: __classPrivateFieldGet(this, _DevvitCustomPost_lastRequest, "f"),
|
|
78
|
-
state: __classPrivateFieldGet(this, _DevvitCustomPost_instances, "a", _DevvitCustomPost_state_get),
|
|
79
66
|
stackDirection: BlockStackDirection.UNRECOGNIZED,
|
|
80
|
-
|
|
81
|
-
experimental: this.useExperimentalBlocks,
|
|
67
|
+
state: __classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").appState,
|
|
82
68
|
}));
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
69
|
+
_DevvitCustomPost_onError.set(this, (type, err) => {
|
|
70
|
+
if (!isCircuitBreaker(err))
|
|
71
|
+
console.error(err);
|
|
72
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-error', { err, type });
|
|
73
|
+
});
|
|
74
|
+
_DevvitCustomPost_onPluginCall.set(this, (_id, serviceName, method, args, _meta) => {
|
|
87
75
|
if (serviceName === RealtimeDefinition.fullName &&
|
|
88
|
-
method === RealtimeDefinition.methods.send.name)
|
|
76
|
+
method === RealtimeDefinition.methods.send.name)
|
|
89
77
|
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-realtime-send', { event: args });
|
|
90
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_localClient, "f")?.onPluginResponse(id, { error: undefined, success: true, value: {} });
|
|
91
|
-
}
|
|
92
78
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
_DevvitCustomPost_onRenderPost.set(this, (req, rsp) => {
|
|
80
|
+
var _a, _b;
|
|
81
|
+
this.renderResponse = rsp;
|
|
82
|
+
if (this.renderResponse?.blocks?.ui) {
|
|
83
|
+
__classPrivateFieldSet(this, _DevvitCustomPost_lastRequest, req.blocks, "f");
|
|
84
|
+
this._rootBlock = this.renderResponse.blocks.ui;
|
|
85
|
+
if (!__classPrivateFieldGet(this, _DevvitCustomPost_rootHeight, "f")) {
|
|
86
|
+
// Lock in the initial height
|
|
87
|
+
__classPrivateFieldSet(this, _DevvitCustomPost_rootHeight, this._rootBlock.config?.rootConfig?.height || DEFAULT_ROOT_HEIGHT, "f");
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
(_a = this._rootBlock).config ?? (_a.config = {});
|
|
91
|
+
(_b = this._rootBlock.config).rootConfig ?? (_b.rootConfig = BlockConfig_Root.fromPartial({}));
|
|
92
|
+
this._rootBlock.config.rootConfig.height = __classPrivateFieldGet(this, _DevvitCustomPost_rootHeight, "f");
|
|
93
|
+
}
|
|
101
94
|
}
|
|
102
95
|
});
|
|
103
|
-
|
|
104
|
-
|
|
96
|
+
_DevvitCustomPost_onUserActionEffect.set(this, (fx) => {
|
|
97
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-effect', {
|
|
98
|
+
effect: fx,
|
|
99
|
+
onEvent: (ev) => __classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").queueEvent(ev),
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
_DevvitCustomPost_onUserActionEvent.set(this, (ev) => {
|
|
103
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").queueRenderPost(BlockRenderEventType.RENDER_USER_ACTION, ev.detail.action.id, ev.detail.action.data);
|
|
104
|
+
});
|
|
105
|
+
this.addEventListener('devvit-user-action', __classPrivateFieldGet(this, _DevvitCustomPost_onUserActionEvent, "f"));
|
|
106
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").onError = __classPrivateFieldGet(this, _DevvitCustomPost_onError, "f");
|
|
107
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").onPluginCall = __classPrivateFieldGet(this, _DevvitCustomPost_onPluginCall, "f");
|
|
108
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").onRenderPost = __classPrivateFieldGet(this, _DevvitCustomPost_onRenderPost, "f");
|
|
109
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").onUserAction = __classPrivateFieldGet(this, _DevvitCustomPost_onUserActionEffect, "f");
|
|
110
|
+
}
|
|
111
|
+
async connectedCallback() {
|
|
112
|
+
super.connectedCallback();
|
|
113
|
+
this._isSuspended = false;
|
|
105
114
|
}
|
|
106
115
|
disconnectedCallback() {
|
|
107
|
-
|
|
116
|
+
this._isSuspended = true;
|
|
117
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").unload();
|
|
108
118
|
super.disconnectedCallback();
|
|
109
119
|
}
|
|
110
120
|
get blocksConfig() {
|
|
@@ -112,6 +122,7 @@ let DevvitCustomPost = class DevvitCustomPost extends LitElement {
|
|
|
112
122
|
return '';
|
|
113
123
|
return b64.fromByteArray(Block.encode(this._rootBlock).finish());
|
|
114
124
|
}
|
|
125
|
+
// to-do [studio]: remove.
|
|
115
126
|
rerender() {
|
|
116
127
|
this._blocksRenderer?.requestUpdate();
|
|
117
128
|
}
|
|
@@ -127,225 +138,54 @@ let DevvitCustomPost = class DevvitCustomPost extends LitElement {
|
|
|
127
138
|
<devvit-blocks-renderer
|
|
128
139
|
class="${this.scheme ?? ''}"
|
|
129
140
|
.block="${this._rootBlock}"
|
|
130
|
-
.renderContext="${__classPrivateFieldGet(this,
|
|
141
|
+
.renderContext="${__classPrivateFieldGet(this, _DevvitCustomPost_newRenderContext, "f")}"
|
|
131
142
|
>
|
|
132
143
|
<slot slot="empty-state-image" name="empty-state-image"></slot>
|
|
133
144
|
</devvit-blocks-renderer>
|
|
134
145
|
${this._isSuspended
|
|
135
146
|
? html `<div class="absolute top-0 left-0 w-full h-full bg-transparent border-none"></div>`
|
|
136
|
-
:
|
|
147
|
+
: nothing}
|
|
137
148
|
</div>`;
|
|
138
149
|
}
|
|
139
150
|
async willUpdate(props) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
__classPrivateFieldGet(this,
|
|
144
|
-
if (__classPrivateFieldGet(this, _DevvitCustomPost_rerenderTimeout, "f") != null)
|
|
145
|
-
clearTimeout(__classPrivateFieldGet(this, _DevvitCustomPost_rerenderTimeout, "f"));
|
|
146
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_rerenderTimeout, undefined, "f");
|
|
147
|
-
}
|
|
148
|
-
if (props.has('localRuntimeCode') && this.localRuntimeCode) {
|
|
149
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_localClient, new BrowserLiteClient(this.localRuntimeCode, (type, err) => __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-error', { type, err }), { callback: __classPrivateFieldGet(this, _DevvitCustomPost_onPluginCall, "f"), plugins: [RealtimeDefinition.fullName] }), "f");
|
|
151
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").meta = this.metadata;
|
|
152
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").postConfig = this.postConfig;
|
|
153
|
+
if (props.has('postId')) {
|
|
154
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").postID = this.postId ? asT3ID(this.postId) : undefined;
|
|
150
155
|
}
|
|
151
156
|
if (props.has('actorRef')) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
else if ((this.bundle && props.has('bundle')) || !__classPrivateFieldGet(this, _DevvitCustomPost_hasInitialRender, "f")) {
|
|
170
|
-
// online only
|
|
171
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_initialRender).call(this);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
else if (props.has('useExperimentalBlocks')) {
|
|
175
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_initialRender).call(this);
|
|
176
|
-
}
|
|
157
|
+
if (!this.actorRef)
|
|
158
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").remote = undefined;
|
|
159
|
+
else if ('As' in this.actorRef)
|
|
160
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").remote = new RemoteApp(this.actorRef);
|
|
161
|
+
else
|
|
162
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").remote = this.actorRef;
|
|
163
|
+
}
|
|
164
|
+
if (props.has('localRuntimeCode'))
|
|
165
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").setLocalSrc(this.localRuntimeCode);
|
|
166
|
+
if (props.has('bundle') && this.bundle) {
|
|
167
|
+
await __classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").load(this.bundle, this.useSandbox);
|
|
168
|
+
// Bundle was _replaced_. Require a new render.
|
|
169
|
+
if (props.get('bundle'))
|
|
170
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").resetAppState();
|
|
171
|
+
}
|
|
172
|
+
if (!__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").rendered)
|
|
173
|
+
__classPrivateFieldGet(this, _DevvitCustomPost_looper, "f").queueRenderPost(BlockRenderEventType.RENDER_INITIAL, undefined, {});
|
|
177
174
|
}
|
|
178
175
|
};
|
|
179
|
-
_DevvitCustomPost_appState = new WeakMap();
|
|
180
|
-
_DevvitCustomPost_customPostActor = new WeakMap();
|
|
181
|
-
_DevvitCustomPost_hasInitialRender = new WeakMap();
|
|
182
176
|
_DevvitCustomPost_lastRequest = new WeakMap();
|
|
183
|
-
|
|
184
|
-
_DevvitCustomPost_rerenderTimeout = new WeakMap();
|
|
177
|
+
_DevvitCustomPost_looper = new WeakMap();
|
|
185
178
|
_DevvitCustomPost_rootHeight = new WeakMap();
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
_DevvitCustomPost_handleUserAction = new WeakMap();
|
|
189
|
-
_DevvitCustomPost_makeRenderContext = new WeakMap();
|
|
190
|
-
_DevvitCustomPost_newRenderRequest = new WeakMap();
|
|
179
|
+
_DevvitCustomPost_newRenderContext = new WeakMap();
|
|
180
|
+
_DevvitCustomPost_onError = new WeakMap();
|
|
191
181
|
_DevvitCustomPost_onPluginCall = new WeakMap();
|
|
192
|
-
|
|
182
|
+
_DevvitCustomPost_onRenderPost = new WeakMap();
|
|
183
|
+
_DevvitCustomPost_onUserActionEffect = new WeakMap();
|
|
184
|
+
_DevvitCustomPost_onUserActionEvent = new WeakMap();
|
|
193
185
|
_DevvitCustomPost_instances = new WeakSet();
|
|
194
186
|
_DevvitCustomPost_bubble = function _DevvitCustomPost_bubble(type, detail) {
|
|
195
187
|
this.dispatchEvent(customEvent(type, detail));
|
|
196
188
|
};
|
|
197
|
-
_DevvitCustomPost_effectEventRender = async function _DevvitCustomPost_effectEventRender(effectType, effectData) {
|
|
198
|
-
await __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_queueRenderPost).call(this, __classPrivateFieldGet(this, _DevvitCustomPost_newRenderRequest, "f").call(this, BlockRenderEventType.RENDER_EFFECT_EVENT, effectType, effectData), undefined);
|
|
199
|
-
};
|
|
200
|
-
_DevvitCustomPost_handleEffects = async function _DevvitCustomPost_handleEffects(renderType, effects) {
|
|
201
|
-
effects.forEach((effect) => {
|
|
202
|
-
if (effect.type === EffectType.EFFECT_SEND_EVENT) {
|
|
203
|
-
if (effect.sendEvent?.event) {
|
|
204
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_queueEvent, "f").call(this, effect.sendEvent.event);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
else if (effect.type === EffectType.EFFECT_RERENDER_UI) {
|
|
208
|
-
if (__classPrivateFieldGet(this, _DevvitCustomPost_rerenderTimeout, "f") != null)
|
|
209
|
-
clearTimeout(__classPrivateFieldGet(this, _DevvitCustomPost_rerenderTimeout, "f"));
|
|
210
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_rerenderTimeout, setTimeout(() => {
|
|
211
|
-
void __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_effectEventRender).call(this, 'rerender-effect', {});
|
|
212
|
-
}, (effect.rerenderUi?.delaySeconds ?? 0) * 1000), "f");
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
if (renderType !== BlockRenderEventType.RENDER_USER_ACTION ||
|
|
216
|
-
USER_ACTION_EFFECTS.includes(effect.type)) {
|
|
217
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-effect', {
|
|
218
|
-
effect,
|
|
219
|
-
onEvent: (ev) => __classPrivateFieldGet(this, _DevvitCustomPost_queueEvent, "f").call(this, ev),
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
};
|
|
225
|
-
_DevvitCustomPost_initialRender = function _DevvitCustomPost_initialRender() {
|
|
226
|
-
if (this._isSuspended) {
|
|
227
|
-
this._isSuspended = false;
|
|
228
|
-
}
|
|
229
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_rootHeight, undefined, "f");
|
|
230
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_hasInitialRender, true, "f");
|
|
231
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_queueRenderPost).call(this, __classPrivateFieldGet(this, _DevvitCustomPost_newRenderRequest, "f").call(this, BlockRenderEventType.RENDER_INITIAL), undefined);
|
|
232
|
-
};
|
|
233
|
-
_DevvitCustomPost_processEvent = async function _DevvitCustomPost_processEvent(ev) {
|
|
234
|
-
const req = {
|
|
235
|
-
event: ev,
|
|
236
|
-
state: __classPrivateFieldGet(this, _DevvitCustomPost_instances, "a", _DevvitCustomPost_state_get),
|
|
237
|
-
};
|
|
238
|
-
let call;
|
|
239
|
-
try {
|
|
240
|
-
call = (await __classPrivateFieldGet(this, _DevvitCustomPost_localClient, "f")?.call('HandleUIEvent', req, this.metadata));
|
|
241
|
-
}
|
|
242
|
-
catch (err) {
|
|
243
|
-
if ((!isCircuitBreaker(err) && __classPrivateFieldGet(this, _DevvitCustomPost_localClient, "f")?.ready) || !__classPrivateFieldGet(this, _DevvitCustomPost_uiEventHandlerActor, "f")) {
|
|
244
|
-
console.error(err);
|
|
245
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-error', { err, type: 'Error' });
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
if (devvit?.logCircuitBreaks)
|
|
249
|
-
console.warn('remote call triggered at', err);
|
|
250
|
-
}
|
|
251
|
-
// Call remote runtime.
|
|
252
|
-
try {
|
|
253
|
-
call = await __classPrivateFieldGet(this, _DevvitCustomPost_uiEventHandlerActor, "f")?.HandleUIEvent(req, this.metadata);
|
|
254
|
-
}
|
|
255
|
-
catch (err) {
|
|
256
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-error', { err, type: 'Error' });
|
|
257
|
-
throw err;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
if (call) {
|
|
261
|
-
// Can only change state on the main queue.
|
|
262
|
-
if (!ev.queue) {
|
|
263
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_appState, call.state ?? {}, "f");
|
|
264
|
-
}
|
|
265
|
-
const renderType = ev.realtimeEvent
|
|
266
|
-
? BlockRenderEventType.RENDER_EFFECT_EVENT
|
|
267
|
-
: BlockRenderEventType.RENDER_USER_ACTION;
|
|
268
|
-
await __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_handleEffects).call(this, renderType, call.effects);
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
_DevvitCustomPost_queueRenderPost = function _DevvitCustomPost_queueRenderPost(req, circuitBreak) {
|
|
272
|
-
void __classPrivateFieldGet(this, _DevvitCustomPost_rpcQueue, "f").add(() => __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_renderPost).call(this, req, circuitBreak),
|
|
273
|
-
// Cut in line to re-render from server response immediately
|
|
274
|
-
{ priority: circuitBreak ? 100 : 0 });
|
|
275
|
-
};
|
|
276
|
-
_DevvitCustomPost_renderPost = async function _DevvitCustomPost_renderPost(req, circuitBreak) {
|
|
277
|
-
var _a, _b;
|
|
278
|
-
let call;
|
|
279
|
-
req.state = __classPrivateFieldGet(this, _DevvitCustomPost_instances, "a", _DevvitCustomPost_state_get);
|
|
280
|
-
try {
|
|
281
|
-
if (circuitBreak)
|
|
282
|
-
throw circuitBreak;
|
|
283
|
-
call = (await __classPrivateFieldGet(this, _DevvitCustomPost_localClient, "f")?.call('RenderPost', req, this.metadata));
|
|
284
|
-
}
|
|
285
|
-
catch (err) {
|
|
286
|
-
// Local runtime call failed.
|
|
287
|
-
if (!circuitBreak && isCircuitBreaker(err)) {
|
|
288
|
-
// Circuit break. Enqueue remote runtime render.
|
|
289
|
-
if (err.response) {
|
|
290
|
-
call = err.response;
|
|
291
|
-
}
|
|
292
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_queueRenderPost).call(this, req, err);
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
// Render now.
|
|
296
|
-
if ((!circuitBreak || !__classPrivateFieldGet(this, _DevvitCustomPost_customPostActor, "f")) && __classPrivateFieldGet(this, _DevvitCustomPost_localClient, "f")?.ready) {
|
|
297
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-error', { err, type: 'Error' });
|
|
298
|
-
console.error(err);
|
|
299
|
-
}
|
|
300
|
-
else {
|
|
301
|
-
if (devvit?.logCircuitBreaks)
|
|
302
|
-
console.warn('remote call triggered at', err);
|
|
303
|
-
}
|
|
304
|
-
// Call remote runtime.
|
|
305
|
-
try {
|
|
306
|
-
call = await __classPrivateFieldGet(this, _DevvitCustomPost_customPostActor, "f")?.RenderPost(req, this.metadata);
|
|
307
|
-
}
|
|
308
|
-
catch (err) {
|
|
309
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_bubble).call(this, 'devvit-ui-error', { err, type: 'Error' });
|
|
310
|
-
throw err;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
if (call) {
|
|
315
|
-
this.renderResponse = call;
|
|
316
|
-
if (this.renderResponse.state) {
|
|
317
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_appState, this.renderResponse.state, "f");
|
|
318
|
-
}
|
|
319
|
-
if (this.renderResponse?.blocks?.ui) {
|
|
320
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_lastRequest, req.blocks, "f");
|
|
321
|
-
this._rootBlock = this.renderResponse.blocks.ui;
|
|
322
|
-
if (!__classPrivateFieldGet(this, _DevvitCustomPost_rootHeight, "f")) {
|
|
323
|
-
// Lock in the initial height
|
|
324
|
-
__classPrivateFieldSet(this, _DevvitCustomPost_rootHeight, this._rootBlock.config?.rootConfig?.height || DEFAULT_ROOT_HEIGHT, "f");
|
|
325
|
-
}
|
|
326
|
-
else {
|
|
327
|
-
(_a = this._rootBlock).config ?? (_a.config = {});
|
|
328
|
-
(_b = this._rootBlock.config).rootConfig ?? (_b.rootConfig = BlockConfig_Root.fromPartial({}));
|
|
329
|
-
this._rootBlock.config.rootConfig.height = __classPrivateFieldGet(this, _DevvitCustomPost_rootHeight, "f");
|
|
330
|
-
}
|
|
331
|
-
await this.updateComplete;
|
|
332
|
-
}
|
|
333
|
-
await __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_handleEffects).call(this, req.blocks.type, this.renderResponse.effects);
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
_DevvitCustomPost_state_get = function _DevvitCustomPost_state_get() {
|
|
337
|
-
const data = { __postData: { thingId: this.postId, config: this.postConfig } };
|
|
338
|
-
return Object.assign({}, __classPrivateFieldGet(this, _DevvitCustomPost_appState, "f"), data);
|
|
339
|
-
};
|
|
340
|
-
_DevvitCustomPost_suspendPost = function _DevvitCustomPost_suspendPost() {
|
|
341
|
-
this._isSuspended = true;
|
|
342
|
-
if (__classPrivateFieldGet(this, _DevvitCustomPost_rerenderTimeout, "f") != null)
|
|
343
|
-
clearTimeout(__classPrivateFieldGet(this, _DevvitCustomPost_rerenderTimeout, "f"));
|
|
344
|
-
__classPrivateFieldGet(this, _DevvitCustomPost_localClient, "f")?.quit();
|
|
345
|
-
};
|
|
346
|
-
_DevvitCustomPost_userActionRender = async function _DevvitCustomPost_userActionRender(actionId, data = {}) {
|
|
347
|
-
await __classPrivateFieldGet(this, _DevvitCustomPost_instances, "m", _DevvitCustomPost_queueRenderPost).call(this, __classPrivateFieldGet(this, _DevvitCustomPost_newRenderRequest, "f").call(this, BlockRenderEventType.RENDER_USER_ACTION, actionId, data), undefined);
|
|
348
|
-
};
|
|
349
189
|
__decorate([
|
|
350
190
|
property({ attribute: false }),
|
|
351
191
|
__metadata("design:type", Object)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { CustomPost, HandleUIEventRequest, HandleUIEventResponse, Metadata, RenderPostRequest, RenderPostResponse, UIEventHandler, UIRequest, UIResponse } from '@devvit/protos';
|
|
2
|
+
import { ActorRef } from '@devvit/runtimes/common/runtime/ActorRef.js';
|
|
3
|
+
/** An app that can render a custom post and respond to events. */
|
|
4
|
+
export type UIApp = CustomPost & UIEventHandler;
|
|
5
|
+
/**
|
|
6
|
+
* Adapts an ActorRef (usually provided by the deprecated BrowserRuntime) to the
|
|
7
|
+
* APIs implemented by a UIApp.
|
|
8
|
+
* @deprecated
|
|
9
|
+
*/
|
|
10
|
+
export declare class RemoteApp implements UIApp {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(ref: ActorRef);
|
|
13
|
+
HandleUIEvent(req: HandleUIEventRequest, meta: Metadata | undefined): Promise<HandleUIEventResponse>;
|
|
14
|
+
RenderPost(req: RenderPostRequest, meta: Metadata | undefined): Promise<RenderPostResponse>;
|
|
15
|
+
RenderPostContent(req: UIRequest, meta: Metadata | undefined): Promise<UIResponse>;
|
|
16
|
+
RenderPostComposer(req: UIRequest, meta: Metadata | undefined): Promise<UIResponse>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=ui-app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui-app.d.ts","sourceRoot":"","sources":["../../library/src/client/ui-app.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,oBAAoB,EACpB,qBAAqB,EACrB,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EAEd,SAAS,EACT,UAAU,EACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AAEvE,kEAAkE;AAClE,MAAM,MAAM,KAAK,GAAG,UAAU,GAAG,cAAc,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,SAAU,YAAW,KAAK;;gBAIzB,GAAG,EAAE,QAAQ;IAKzB,aAAa,CACX,GAAG,EAAE,oBAAoB,EACzB,IAAI,EAAE,QAAQ,GAAG,SAAS,GACzB,OAAO,CAAC,qBAAqB,CAAC;IAIjC,UAAU,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAI3F,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAIlF,kBAAkB,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;CAGpF"}
|
package/client/ui-app.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _RemoteApp_customPost, _RemoteApp_uiEventHandler;
|
|
13
|
+
import { CustomPostDefinition, UIEventHandlerDefinition, } from '@devvit/protos';
|
|
14
|
+
/**
|
|
15
|
+
* Adapts an ActorRef (usually provided by the deprecated BrowserRuntime) to the
|
|
16
|
+
* APIs implemented by a UIApp.
|
|
17
|
+
* @deprecated
|
|
18
|
+
*/
|
|
19
|
+
export class RemoteApp {
|
|
20
|
+
constructor(ref) {
|
|
21
|
+
_RemoteApp_customPost.set(this, void 0);
|
|
22
|
+
_RemoteApp_uiEventHandler.set(this, void 0);
|
|
23
|
+
__classPrivateFieldSet(this, _RemoteApp_customPost, ref.As(CustomPostDefinition), "f");
|
|
24
|
+
__classPrivateFieldSet(this, _RemoteApp_uiEventHandler, ref.As(UIEventHandlerDefinition), "f");
|
|
25
|
+
}
|
|
26
|
+
HandleUIEvent(req, meta) {
|
|
27
|
+
return __classPrivateFieldGet(this, _RemoteApp_uiEventHandler, "f").HandleUIEvent(req, meta);
|
|
28
|
+
}
|
|
29
|
+
RenderPost(req, meta) {
|
|
30
|
+
return __classPrivateFieldGet(this, _RemoteApp_customPost, "f").RenderPost(req, meta);
|
|
31
|
+
}
|
|
32
|
+
RenderPostContent(req, meta) {
|
|
33
|
+
return __classPrivateFieldGet(this, _RemoteApp_customPost, "f").RenderPostContent(req, meta);
|
|
34
|
+
}
|
|
35
|
+
RenderPostComposer(req, meta) {
|
|
36
|
+
return __classPrivateFieldGet(this, _RemoteApp_customPost, "f").RenderPostComposer(req, meta);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
_RemoteApp_customPost = new WeakMap(), _RemoteApp_uiEventHandler = new WeakMap();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devvit/ui-renderer",
|
|
3
|
-
"version": "0.10.17-next-2024-02-
|
|
3
|
+
"version": "0.10.17-next-2024-02-26-9e49b4eeb.0",
|
|
4
4
|
"license": "BSD-3-Clause",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -54,13 +54,13 @@
|
|
|
54
54
|
},
|
|
55
55
|
"types": "./index.d.ts",
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@devvit/protos": "0.10.17-next-2024-02-
|
|
58
|
-
"@devvit/runtime-lite": "0.10.17-next-2024-02-
|
|
59
|
-
"@devvit/runtimes": "0.10.17-next-2024-02-
|
|
60
|
-
"@devvit/shared-types": "0.10.17-next-2024-02-
|
|
57
|
+
"@devvit/protos": "0.10.17-next-2024-02-26-9e49b4eeb.0",
|
|
58
|
+
"@devvit/runtime-lite": "0.10.17-next-2024-02-26-9e49b4eeb.0",
|
|
59
|
+
"@devvit/runtimes": "0.10.17-next-2024-02-26-9e49b4eeb.0",
|
|
60
|
+
"@devvit/shared-types": "0.10.17-next-2024-02-26-9e49b4eeb.0",
|
|
61
61
|
"@dotlottie/player-component": "2.7.2",
|
|
62
62
|
"p-queue": "7.3.4",
|
|
63
|
-
"rxjs": "7.
|
|
63
|
+
"rxjs": "7.8.1"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@reddit/baseplate": "1.1.3",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"devDependencies": {
|
|
85
85
|
"@devvit/eslint-config": "0.10.16",
|
|
86
86
|
"@devvit/repo-tools": "0.10.16",
|
|
87
|
-
"@devvit/tsconfig": "0.10.17-next-2024-02-
|
|
87
|
+
"@devvit/tsconfig": "0.10.17-next-2024-02-26-9e49b4eeb.0",
|
|
88
88
|
"@lit-labs/ssr": "^2.2.3",
|
|
89
89
|
"@lit/localize": "0.11.4",
|
|
90
90
|
"@open-wc/testing-helpers": "2.3.0",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"directory": "dist"
|
|
118
118
|
},
|
|
119
119
|
"source": "./src/index.ts",
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "145863b65a5fbd4d78287d528917021d67b9079a"
|
|
121
121
|
}
|
package/types/devvit-global.d.ts
CHANGED
|
@@ -2,24 +2,22 @@ declare global {
|
|
|
2
2
|
var devvit: DevvitGlobal | undefined;
|
|
3
3
|
}
|
|
4
4
|
export type DevvitGlobal = {
|
|
5
|
-
/** Report circuit break errors in devvit-custom-post. */
|
|
6
|
-
|
|
5
|
+
/** Report circuit break and local errors in devvit-custom-post. */
|
|
6
|
+
logLocalErrors?: boolean | undefined;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* The bookmarklet to enable full debugging is:
|
|
10
10
|
*
|
|
11
11
|
* ```
|
|
12
|
-
* (() => {
|
|
12
|
+
* javascript:(() => {
|
|
13
13
|
* globalThis.devvit = {};
|
|
14
|
-
* globalThis.devvit.
|
|
14
|
+
* globalThis.devvit.logLocalErrors = true;
|
|
15
15
|
* const url = new URL(location.href);
|
|
16
|
-
* url.searchParams.set('
|
|
16
|
+
* url.searchParams.set('devvitLogLocalErrors', '');
|
|
17
17
|
* history.replaceState(undefined, '', url);
|
|
18
18
|
* console.log(`devvit debug enabled`, globalThis.devvit);
|
|
19
19
|
* })()
|
|
20
20
|
* ```
|
|
21
|
-
*
|
|
22
|
-
* Just add a `javascript:` protocol and remove newlines.
|
|
23
21
|
*/
|
|
24
22
|
export declare function initDevvitGlobal(): void;
|
|
25
23
|
//# sourceMappingURL=devvit-global.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devvit-global.d.ts","sourceRoot":"","sources":["../../library/src/types/devvit-global.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,
|
|
1
|
+
{"version":3,"file":"devvit-global.d.ts","sourceRoot":"","sources":["../../library/src/types/devvit-global.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,mEAAmE;IACnE,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC"}
|
package/types/devvit-global.js
CHANGED
|
@@ -2,23 +2,21 @@
|
|
|
2
2
|
* The bookmarklet to enable full debugging is:
|
|
3
3
|
*
|
|
4
4
|
* ```
|
|
5
|
-
* (() => {
|
|
5
|
+
* javascript:(() => {
|
|
6
6
|
* globalThis.devvit = {};
|
|
7
|
-
* globalThis.devvit.
|
|
7
|
+
* globalThis.devvit.logLocalErrors = true;
|
|
8
8
|
* const url = new URL(location.href);
|
|
9
|
-
* url.searchParams.set('
|
|
9
|
+
* url.searchParams.set('devvitLogLocalErrors', '');
|
|
10
10
|
* history.replaceState(undefined, '', url);
|
|
11
11
|
* console.log(`devvit debug enabled`, globalThis.devvit);
|
|
12
12
|
* })()
|
|
13
13
|
* ```
|
|
14
|
-
*
|
|
15
|
-
* Just add a `javascript:` protocol and remove newlines.
|
|
16
14
|
*/
|
|
17
15
|
export function initDevvitGlobal() {
|
|
18
16
|
var _a;
|
|
19
17
|
// Initialize defensively to honor any initializations that might occur in a
|
|
20
|
-
// temporary hack elsewhere.
|
|
21
|
-
const url = new URL(location.href);
|
|
18
|
+
// temporary hack elsewhere. `globalThis.location` check allows Node.js usage.
|
|
19
|
+
const url = new URL(globalThis.location ? location.href : 'file://');
|
|
22
20
|
globalThis.devvit ?? (globalThis.devvit = {});
|
|
23
|
-
(_a = globalThis.devvit).
|
|
21
|
+
(_a = globalThis.devvit).logLocalErrors ?? (_a.logLocalErrors = url.searchParams.has('devvitLogLocalErrors'));
|
|
24
22
|
}
|