@devvit/public-api 0.11.4-next-2024-12-03-c18e28c44.0 → 0.11.4-next-2024-12-03-534d9fc60.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.
@@ -1,12 +1,33 @@
1
1
  import type { JSONValue } from '@devvit/shared-types/json.js';
2
2
  import type { AsyncUseStateInitializer, UseAsyncResult } from '../../../../types/hooks.js';
3
- export type AsyncOptions = {
3
+ export type AsyncOptions<S extends JSONValue> = {
4
4
  /**
5
5
  * The data loader will re-run if the value of `depends` changes.
6
6
  */
7
7
  depends?: JSONValue;
8
+ /**
9
+ * A callback that will be called after the data is loaded, regardless of whether it succeeds or fails.
10
+ * This is a good place to run setStates or other side effects, because calling a setState in the main
11
+ * body is not allowed.
12
+ *
13
+ * useAsync(async () => {
14
+ * const response = await fetch(`https://date.api/today?timezone=${timezone}`);
15
+ * return response.json();
16
+ * }, {
17
+ * depends: [timezone],
18
+ * finally: (data, error) => {
19
+ * if (error) {
20
+ * console.error("Failed to load date data:", error);
21
+ * } else {
22
+ * setTodayDate(data['currentDate']);
23
+ * }
24
+ * },
25
+ * });
26
+ *
27
+ */
28
+ finally?: (data: S | null, error: Error | null) => void;
8
29
  };
9
- export type LoadState = 'initial' | 'loading' | 'loaded' | 'error' | 'disabled';
30
+ export type LoadState = 'initial' | 'loading' | 'loaded' | 'error';
10
31
  /**
11
32
  * This tries to save an error into the state. If the error is a circuit breaker, it will throw the error instead,
12
33
  * as those errors are not meant to be saved in state.
@@ -24,5 +45,5 @@ export declare function toSerializableErrorOrCircuitBreak(e: unknown): {
24
45
  * @param initializer -- any async function that returns a JSONValue
25
46
  * @returns UseAsyncResult<S>
26
47
  */
27
- export declare function useAsync<S extends JSONValue>(initializer: AsyncUseStateInitializer<S>, options?: AsyncOptions): UseAsyncResult<S>;
48
+ export declare function useAsync<S extends JSONValue>(initializer: AsyncUseStateInitializer<S>, options?: AsyncOptions<S>): UseAsyncResult<S>;
28
49
  //# sourceMappingURL=useAsync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAsync.d.ts","sourceRoot":"","sources":["../../../../../src/devvit/internals/blocks/handler/useAsync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAK3F,MAAM,MAAM,YAAY,GAAG;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAEhF;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,EAAE,OAAO,GAAG;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAYA;AA2GD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAC1C,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAC,EACxC,OAAO,GAAE,YAAiB,GACzB,cAAc,CAAC,CAAC,CAAC,CAanB"}
1
+ {"version":3,"file":"useAsync.d.ts","sourceRoot":"","sources":["../../../../../src/devvit/internals/blocks/handler/useAsync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,KAAK,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAK3F,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,IAAI;IAC9C;;OAEG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IAEpB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;CACzD,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEnE;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,EAAE,OAAO,GAAG;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAYA;AAoHD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAC1C,WAAW,EAAE,wBAAwB,CAAC,CAAC,CAAC,EACxC,OAAO,GAAE,YAAY,CAAC,CAAC,CAAM,GAC5B,cAAc,CAAC,CAAC,CAAC,CAanB"}
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
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
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _AsyncHook_debug, _AsyncHook_hookId, _AsyncHook_invalidate, _AsyncHook_ctx;
12
+ var _AsyncHook_debug, _AsyncHook_hookId, _AsyncHook_invalidate, _AsyncHook_ctx, _AsyncHook_options;
13
13
  import { UIEventScope } from '@devvit/protos';
14
14
  import { CIRCUIT_BREAKER_MSG } from '@devvit/shared-types/CircuitBreaker.js';
15
15
  import { StringUtil } from '@devvit/shared-types/StringUtil.js';
@@ -42,6 +42,7 @@ class AsyncHook {
42
42
  _AsyncHook_hookId.set(this, void 0);
43
43
  _AsyncHook_invalidate.set(this, void 0);
44
44
  _AsyncHook_ctx.set(this, void 0);
45
+ _AsyncHook_options.set(this, void 0);
45
46
  __classPrivateFieldSet(this, _AsyncHook_debug, !!params.context.devvitContext.debug.useAsync, "f");
46
47
  if (__classPrivateFieldGet(this, _AsyncHook_debug, "f"))
47
48
  console.debug('[useAsync] v1', options);
@@ -51,14 +52,12 @@ class AsyncHook {
51
52
  __classPrivateFieldSet(this, _AsyncHook_invalidate, params.invalidate, "f");
52
53
  __classPrivateFieldSet(this, _AsyncHook_ctx, params.context, "f");
53
54
  this.localDepends = options.depends ?? null;
55
+ __classPrivateFieldSet(this, _AsyncHook_options, options, "f");
54
56
  }
55
57
  /**
56
58
  * After we look at our state, we need to decide if we need to dispatch a request to load the data.
57
59
  */
58
60
  onStateLoaded() {
59
- if (this.state.load_state === 'disabled') {
60
- return;
61
- }
62
61
  if (__classPrivateFieldGet(this, _AsyncHook_debug, "f"))
63
62
  console.debug('[useAsync] async onLoad ', __classPrivateFieldGet(this, _AsyncHook_hookId, "f"), this.state);
64
63
  if (__classPrivateFieldGet(this, _AsyncHook_debug, "f"))
@@ -117,6 +116,9 @@ class AsyncHook {
117
116
  error: event.asyncResponse.error ?? null,
118
117
  load_state: event.asyncResponse.error ? 'error' : 'loaded',
119
118
  };
119
+ if (__classPrivateFieldGet(this, _AsyncHook_options, "f").finally) {
120
+ await __classPrivateFieldGet(this, _AsyncHook_options, "f").finally(this.state.data, this.state.error ? new Error(this.state.error?.message ?? 'Unknown error') : null);
121
+ }
120
122
  __classPrivateFieldGet(this, _AsyncHook_invalidate, "f").call(this);
121
123
  }
122
124
  else {
@@ -129,7 +131,7 @@ class AsyncHook {
129
131
  }
130
132
  }
131
133
  }
132
- _AsyncHook_debug = new WeakMap(), _AsyncHook_hookId = new WeakMap(), _AsyncHook_invalidate = new WeakMap(), _AsyncHook_ctx = new WeakMap();
134
+ _AsyncHook_debug = new WeakMap(), _AsyncHook_hookId = new WeakMap(), _AsyncHook_invalidate = new WeakMap(), _AsyncHook_ctx = new WeakMap(), _AsyncHook_options = new WeakMap();
133
135
  /**
134
136
  * This is the preferred way to handle async state in Devvit.
135
137
  *
package/meta.json CHANGED
@@ -10825,7 +10825,7 @@
10825
10825
  "format": "esm"
10826
10826
  },
10827
10827
  "src/devvit/internals/blocks/handler/useAsync.ts": {
10828
- "bytes": 5930,
10828
+ "bytes": 6958,
10829
10829
  "imports": [
10830
10830
  {
10831
10831
  "path": "../protos/dist/index.js",
@@ -12869,7 +12869,7 @@
12869
12869
  "bytesInOutput": 56
12870
12870
  },
12871
12871
  "src/devvit/internals/blocks/handler/useAsync.ts": {
12872
- "bytesInOutput": 4475
12872
+ "bytesInOutput": 4784
12873
12873
  },
12874
12874
  "src/devvit/internals/blocks/handler/useState.ts": {
12875
12875
  "bytesInOutput": 3770
@@ -12971,7 +12971,7 @@
12971
12971
  "bytesInOutput": 370
12972
12972
  }
12973
12973
  },
12974
- "bytes": 12841370
12974
+ "bytes": 12843271
12975
12975
  }
12976
12976
  }
12977
12977
  }
package/meta.min.json CHANGED
@@ -3685,7 +3685,7 @@
3685
3685
  "format": "esm"
3686
3686
  },
3687
3687
  "src/devvit/internals/blocks/handler/useAsync.ts": {
3688
- "bytes": 5930,
3688
+ "bytes": 6958,
3689
3689
  "imports": [
3690
3690
  {
3691
3691
  "path": "@devvit/protos",
@@ -4789,7 +4789,7 @@
4789
4789
  "imports": [],
4790
4790
  "exports": [],
4791
4791
  "inputs": {},
4792
- "bytes": 1233854
4792
+ "bytes": 1235094
4793
4793
  },
4794
4794
  "dist/public-api.min.js": {
4795
4795
  "imports": [
@@ -5550,7 +5550,7 @@
5550
5550
  "bytesInOutput": 29
5551
5551
  },
5552
5552
  "src/devvit/internals/blocks/handler/useAsync.ts": {
5553
- "bytesInOutput": 2297
5553
+ "bytesInOutput": 2439
5554
5554
  },
5555
5555
  "src/devvit/internals/blocks/handler/ContextBuilder.ts": {
5556
5556
  "bytesInOutput": 530
@@ -5634,7 +5634,7 @@
5634
5634
  "bytesInOutput": 178
5635
5635
  }
5636
5636
  },
5637
- "bytes": 263507
5637
+ "bytes": 263649
5638
5638
  }
5639
5639
  }
5640
5640
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devvit/public-api",
3
- "version": "0.11.4-next-2024-12-03-c18e28c44.0",
3
+ "version": "0.11.4-next-2024-12-03-534d9fc60.0",
4
4
  "license": "BSD-3-Clause",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,8 +30,8 @@
30
30
  },
31
31
  "types": "./index.d.ts",
32
32
  "dependencies": {
33
- "@devvit/protos": "0.11.4-next-2024-12-03-c18e28c44.0",
34
- "@devvit/shared-types": "0.11.4-next-2024-12-03-c18e28c44.0",
33
+ "@devvit/protos": "0.11.4-next-2024-12-03-534d9fc60.0",
34
+ "@devvit/shared-types": "0.11.4-next-2024-12-03-534d9fc60.0",
35
35
  "base64-js": "1.5.1",
36
36
  "clone-deep": "4.0.1",
37
37
  "core-js": "3.27.2",
@@ -39,8 +39,8 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@ampproject/filesize": "4.3.0",
42
- "@devvit/repo-tools": "0.11.4-next-2024-12-03-c18e28c44.0",
43
- "@devvit/tsconfig": "0.11.4-next-2024-12-03-c18e28c44.0",
42
+ "@devvit/repo-tools": "0.11.4-next-2024-12-03-534d9fc60.0",
43
+ "@devvit/tsconfig": "0.11.4-next-2024-12-03-534d9fc60.0",
44
44
  "@microsoft/api-extractor": "7.41.0",
45
45
  "@reddit/faceplate-ui": "18.0.1",
46
46
  "@types/clone-deep": "4.0.1",
@@ -63,5 +63,5 @@
63
63
  }
64
64
  },
65
65
  "source": "./src/index.ts",
66
- "gitHead": "1713fc9de3d013b34268e022f337a3389afd6d89"
66
+ "gitHead": "b16112746286848525cdeed04e9c342a0508f931"
67
67
  }
package/public-api.d.ts CHANGED
@@ -1235,11 +1235,32 @@ declare const AsyncError_2: {
1235
1235
  fromPartial(object: DeepPartial_73<AsyncError_2>): AsyncError_2;
1236
1236
  };
1237
1237
 
1238
- declare type AsyncOptions = {
1238
+ declare type AsyncOptions<S extends JSONValue> = {
1239
1239
  /**
1240
1240
  * The data loader will re-run if the value of `depends` changes.
1241
1241
  */
1242
1242
  depends?: JSONValue;
1243
+ /**
1244
+ * A callback that will be called after the data is loaded, regardless of whether it succeeds or fails.
1245
+ * This is a good place to run setStates or other side effects, because calling a setState in the main
1246
+ * body is not allowed.
1247
+ *
1248
+ * useAsync(async () => {
1249
+ * const response = await fetch(`https://date.api/today?timezone=${timezone}`);
1250
+ * return response.json();
1251
+ * }, {
1252
+ * depends: [timezone],
1253
+ * finally: (data, error) => {
1254
+ * if (error) {
1255
+ * console.error("Failed to load date data:", error);
1256
+ * } else {
1257
+ * setTodayDate(data['currentDate']);
1258
+ * }
1259
+ * },
1260
+ * });
1261
+ *
1262
+ */
1263
+ finally?: (data: S | null, error: Error | null) => void;
1243
1264
  };
1244
1265
 
1245
1266
  declare interface AsyncRequest {
@@ -50038,7 +50059,7 @@ declare type UrlString = string;
50038
50059
  * @param initializer -- any async function that returns a JSONValue
50039
50060
  * @returns UseAsyncResult<S>
50040
50061
  */
50041
- export declare function useAsync<S extends JSONValue>(initializer: AsyncUseStateInitializer<S>, options?: AsyncOptions): UseAsyncResult<S>;
50062
+ export declare function useAsync<S extends JSONValue>(initializer: AsyncUseStateInitializer<S>, options?: AsyncOptions<S>): UseAsyncResult<S>;
50042
50063
 
50043
50064
  export declare type UseAsyncResult<S> = {
50044
50065
  data: S | null;