@devvit/public-api 0.10.23-next-2024-07-02-c8b9ec453.0 → 0.10.23-next-2024-07-23-5e7d46268.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. package/apis/AssetsClient/AssetsClient.d.ts +0 -6
  2. package/apis/AssetsClient/AssetsClient.d.ts.map +1 -1
  3. package/apis/AssetsClient/AssetsClient.js +12 -26
  4. package/apis/makeAPIClients.d.ts.map +1 -1
  5. package/apis/makeAPIClients.js +2 -2
  6. package/apis/realtime/RealtimeClient.d.ts +2 -2
  7. package/apis/realtime/RealtimeClient.d.ts.map +1 -1
  8. package/apis/realtime/RealtimeClient.js +2 -2
  9. package/apis/reddit/RedditAPIClient.d.ts +2 -10
  10. package/apis/reddit/RedditAPIClient.d.ts.map +1 -1
  11. package/apis/reddit/RedditAPIClient.js +1 -11
  12. package/apis/reddit/models/Comment.d.ts +0 -2
  13. package/apis/reddit/models/Comment.d.ts.map +1 -1
  14. package/apis/reddit/models/Comment.js +2 -12
  15. package/apis/reddit/models/Post.d.ts +0 -2
  16. package/apis/reddit/models/Post.d.ts.map +1 -1
  17. package/apis/reddit/models/Post.js +2 -12
  18. package/apis/reddit/models/Subreddit.d.ts +1 -17
  19. package/apis/reddit/models/Subreddit.d.ts.map +1 -1
  20. package/apis/reddit/models/Subreddit.js +0 -15
  21. package/apis/reddit/models/User.d.ts.map +1 -1
  22. package/apis/reddit/models/User.js +2 -1
  23. package/apis/scheduler/SchedulerClient.d.ts +1 -1
  24. package/apis/scheduler/SchedulerClient.d.ts.map +1 -1
  25. package/apis/ui/UIClient.d.ts +3 -3
  26. package/apis/ui/UIClient.d.ts.map +1 -1
  27. package/apis/ui/helpers/assertValidFormFields.d.ts +2 -2
  28. package/apis/ui/helpers/assertValidFormFields.d.ts.map +1 -1
  29. package/apis/ui/helpers/getFormValues.d.ts +2 -2
  30. package/apis/ui/helpers/getFormValues.d.ts.map +1 -1
  31. package/apis/ui/helpers/getFormValues.js +1 -3
  32. package/apis/ui/helpers/transformForm.d.ts +1 -1
  33. package/apis/ui/helpers/transformForm.d.ts.map +1 -1
  34. package/devvit/Devvit.d.ts +6 -8
  35. package/devvit/Devvit.d.ts.map +1 -1
  36. package/devvit/Devvit.js +2 -10
  37. package/devvit/internals/blocks/BlocksReconciler.d.ts.map +1 -1
  38. package/devvit/internals/blocks/BlocksReconciler.js +5 -25
  39. package/devvit/internals/blocks/BlocksTransformer.d.ts +2 -2
  40. package/devvit/internals/blocks/BlocksTransformer.d.ts.map +1 -1
  41. package/devvit/internals/blocks/BlocksTransformer.js +3 -3
  42. package/devvit/internals/blocks/handler/BlocksHandler.d.ts +0 -4
  43. package/devvit/internals/blocks/handler/BlocksHandler.d.ts.map +1 -1
  44. package/devvit/internals/blocks/handler/BlocksHandler.js +9 -33
  45. package/devvit/internals/blocks/handler/ContextBuilder.d.ts.map +1 -1
  46. package/devvit/internals/blocks/handler/ContextBuilder.js +8 -3
  47. package/devvit/internals/blocks/handler/RenderContext.d.ts +1 -5
  48. package/devvit/internals/blocks/handler/RenderContext.d.ts.map +1 -1
  49. package/devvit/internals/blocks/handler/RenderContext.js +3 -30
  50. package/devvit/internals/blocks/handler/UIClient.d.ts +4 -4
  51. package/devvit/internals/blocks/handler/UIClient.d.ts.map +1 -1
  52. package/devvit/internals/blocks/handler/test-helpers.d.ts +0 -1
  53. package/devvit/internals/blocks/handler/test-helpers.d.ts.map +1 -1
  54. package/devvit/internals/blocks/handler/test-helpers.js +0 -3
  55. package/devvit/internals/blocks/handler/types.d.ts +9 -15
  56. package/devvit/internals/blocks/handler/types.d.ts.map +1 -1
  57. package/devvit/internals/blocks/handler/useAsync.d.ts.map +1 -1
  58. package/devvit/internals/blocks/handler/useAsync.js +13 -17
  59. package/devvit/internals/blocks/handler/useChannel.d.ts +1 -2
  60. package/devvit/internals/blocks/handler/useChannel.d.ts.map +1 -1
  61. package/devvit/internals/blocks/handler/useChannel.js +13 -49
  62. package/devvit/internals/blocks/handler/useForm.d.ts +5 -18
  63. package/devvit/internals/blocks/handler/useForm.d.ts.map +1 -1
  64. package/devvit/internals/blocks/handler/useForm.js +6 -3
  65. package/devvit/internals/blocks/handler/useState.d.ts +1 -1
  66. package/devvit/internals/blocks/handler/useState.d.ts.map +1 -1
  67. package/devvit/internals/blocks/handler/useState.js +14 -14
  68. package/devvit/internals/blocks/useChannel.d.ts.map +1 -1
  69. package/devvit/internals/blocks/useChannel.js +2 -15
  70. package/devvit/internals/blocks/useForm.d.ts.map +1 -1
  71. package/devvit/internals/context.d.ts.map +1 -1
  72. package/devvit/internals/context.js +13 -16
  73. package/index.d.ts +0 -1
  74. package/index.d.ts.map +1 -1
  75. package/index.js +0 -1
  76. package/meta.json +309 -311
  77. package/meta.min.json +116 -186
  78. package/package.json +8 -8
  79. package/public-api.d.ts +1750 -2042
  80. package/public-api.iife.js +7282 -7007
  81. package/public-api.min.js +5 -5
  82. package/public-api.min.js.map +4 -4
  83. package/types/context.d.ts +3 -5
  84. package/types/context.d.ts.map +1 -1
  85. package/types/data.d.ts +3 -3
  86. package/types/data.d.ts.map +1 -1
  87. package/types/form.d.ts +17 -28
  88. package/types/form.d.ts.map +1 -1
  89. package/types/hooks.d.ts +7 -37
  90. package/types/hooks.d.ts.map +1 -1
  91. package/types/realtime.d.ts +3 -3
  92. package/types/realtime.d.ts.map +1 -1
  93. package/types/scheduler.d.ts +14 -15
  94. package/types/scheduler.d.ts.map +1 -1
  95. package/types/ui-client.d.ts +4 -4
  96. package/types/ui-client.d.ts.map +1 -1
  97. package/devvit/internals/blocks/handler/cache.d.ts +0 -9
  98. package/devvit/internals/blocks/handler/cache.d.ts.map +0 -1
  99. package/devvit/internals/blocks/handler/cache.js +0 -5
  100. package/devvit/internals/blocks/handler/cache.test.d.ts.map +0 -1
  101. package/devvit/internals/blocks/handler/promise_cache.d.ts +0 -67
  102. package/devvit/internals/blocks/handler/promise_cache.d.ts.map +0 -1
  103. package/devvit/internals/blocks/handler/promise_cache.js +0 -239
  104. package/types/context.test.d.ts.map +0 -1
  105. package/version.json +0 -75
@@ -1,239 +0,0 @@
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 _PromiseCache_instances, _PromiseCache_redis, _PromiseCache_localCache, _PromiseCache_clock, _PromiseCache_state, _PromiseCache_localCachedAnswer, _PromiseCache_maybeRefreshCache, _PromiseCache_refreshCache, _PromiseCache_pollForCache, _PromiseCache_updateCache, _PromiseCache_calculateRamp, _PromiseCache_redisEntry, _PromiseCache_enforceTTL;
13
- export const SystemClock = {
14
- now() {
15
- return new Date();
16
- },
17
- };
18
- export function _namespaced(key) {
19
- return `__autocache__${key}`;
20
- }
21
- export function _lock(key) {
22
- return `__lock__${key}`;
23
- }
24
- const pollEvery = 300; // milli
25
- const maxPollingTimeout = 1000; // milli
26
- const minTtlValue = 5000;
27
- export const retryLimit = 3;
28
- const errorRetryProbability = 0.1;
29
- export const clientRetryDelay = 1000;
30
- export const allowStaleFor = 30000;
31
- function _unwrap(entry) {
32
- if (entry.error) {
33
- throw new Error(entry.error);
34
- }
35
- return entry.value;
36
- }
37
- /**
38
- * Refactored out into a class to allow for easier testing and clarity of purpose.
39
- *
40
- * This class is responsible for managing the caching of promises. It is a layered cache, meaning it will first check
41
- * the local cache, then the redis cache, and finally the source of truth. It will also handle refreshing the cache according
42
- * to the TTL and error handling.
43
- *
44
- * Please note that in order to prevent a stampede of requests to the source of truth, we use a lock in redis to ensure only one
45
- * request is made to the source of truth at a time. If the lock is obtained, the cache will be updated and the lock will be released.
46
- *
47
- * Additionally, we use a polling mechanism to fetch the cache if the lock is not obtained. This is to prevent unnecessary errors.
48
- *
49
- * Finally, we also want to prevent stampedes against redis for the lock election and the retries. We use a ramping probability to ease in the
50
- * attempts to get the lock, and not every error will trigger a retry.
51
- *
52
- * This means that the cache will be eventually consistent, but will not be immediately consistent. This is a tradeoff we are willing to make.
53
- * Additionally, this means that the TTL is not precice. The cache may be updated a bit more often than the TTL, but it will not be updated less often.
54
- *
55
- */
56
- export class PromiseCache {
57
- constructor(redis, state, clock = SystemClock) {
58
- _PromiseCache_instances.add(this);
59
- _PromiseCache_redis.set(this, void 0);
60
- /**
61
- * LocalCache is just an aliased reference to this.#state. Mutations to
62
- * this object will also mutate this.#state
63
- */
64
- _PromiseCache_localCache.set(this, {});
65
- _PromiseCache_clock.set(this, void 0);
66
- _PromiseCache_state.set(this, void 0);
67
- __classPrivateFieldSet(this, _PromiseCache_redis, redis, "f");
68
- __classPrivateFieldSet(this, _PromiseCache_state, state, "f");
69
- __classPrivateFieldSet(this, _PromiseCache_clock, clock, "f");
70
- }
71
- /**
72
- * This is the public API for the cache. Call this method to cache a promise.
73
- *
74
- * @param closure
75
- * @param options
76
- * @returns
77
- */
78
- async cache(closure, options) {
79
- var _a;
80
- (_a = __classPrivateFieldGet(this, _PromiseCache_state, "f")).__cache ?? (_a.__cache = {});
81
- __classPrivateFieldSet(this, _PromiseCache_localCache, __classPrivateFieldGet(this, _PromiseCache_state, "f").__cache, "f");
82
- __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_enforceTTL).call(this, options);
83
- const localCachedAnswer = __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_localCachedAnswer).call(this, options.key);
84
- if (localCachedAnswer !== undefined) {
85
- return localCachedAnswer;
86
- }
87
- const existing = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_redisEntry).call(this, options.key);
88
- const entry = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_maybeRefreshCache).call(this, options, existing, closure);
89
- return _unwrap(entry);
90
- }
91
- }
92
- _PromiseCache_redis = new WeakMap(), _PromiseCache_localCache = new WeakMap(), _PromiseCache_clock = new WeakMap(), _PromiseCache_state = new WeakMap(), _PromiseCache_instances = new WeakSet(), _PromiseCache_localCachedAnswer = function _PromiseCache_localCachedAnswer(key) {
93
- const val = __classPrivateFieldGet(this, _PromiseCache_localCache, "f")[key];
94
- if (val) {
95
- const now = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime();
96
- const hasRetryableError = val?.error &&
97
- val?.errorTime &&
98
- val.errorCount < retryLimit &&
99
- Math.random() < errorRetryProbability &&
100
- val.errorTime + clientRetryDelay < now;
101
- const expired = val?.expires && val.expires < now && val.checkedAt + clientRetryDelay < now;
102
- if (expired || hasRetryableError) {
103
- delete __classPrivateFieldGet(this, _PromiseCache_localCache, "f")[key];
104
- return undefined;
105
- }
106
- else {
107
- return _unwrap(val);
108
- }
109
- }
110
- return undefined;
111
- }, _PromiseCache_maybeRefreshCache =
112
- /**
113
- * If we've bothered to check redis, we're already on the backend. Let's see if the cache either (1) contains an error, (2)
114
- * is expired, (3) is missing, or (4) is about to expire. If any of these are true, we'll refresh the cache based on heuristics.
115
- *
116
- * We'll always refresh if missing or expired, but its probabilistic if we'll refresh if about to expire or if we have an error.
117
- */
118
- async function _PromiseCache_maybeRefreshCache(options, entry, closure) {
119
- const expires = entry?.expires;
120
- const rampProbability = expires ? __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_calculateRamp).call(this, expires) : 1;
121
- if (!entry ||
122
- (entry?.error && entry.errorCount < retryLimit && errorRetryProbability > Math.random()) ||
123
- rampProbability > Math.random()) {
124
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_refreshCache).call(this, options, entry, closure);
125
- }
126
- else {
127
- return entry;
128
- }
129
- }, _PromiseCache_refreshCache =
130
- /**
131
- * The conditions for refreshing the cache are handled in the calling method, which should be
132
- * #maybeRefreshCache.
133
- *
134
- * If you don't win the lock, you'll poll for the cache. If you don't get the cache within maxPollingTimeout, you'll throw an error.
135
- */
136
- async function _PromiseCache_refreshCache(options, entry, closure) {
137
- const lockKey = _lock(options.key);
138
- const now = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime();
139
- /**
140
- * The write lock should last for a while, but not the full TTL. Hopefully write attempts settle down after a while.
141
- */
142
- const lockExpiration = new Date(now + options.ttl / 2);
143
- const lockObtained = await __classPrivateFieldGet(this, _PromiseCache_redis, "f").set(lockKey, '1', {
144
- expiration: lockExpiration,
145
- nx: true,
146
- });
147
- if (lockObtained) {
148
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_updateCache).call(this, options.key, entry, closure, options.ttl);
149
- }
150
- else if (entry) {
151
- // This entry is still valid, return it
152
- return entry;
153
- }
154
- else {
155
- const start = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now();
156
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_pollForCache).call(this, start, options.key, options.ttl);
157
- }
158
- }, _PromiseCache_pollForCache = async function _PromiseCache_pollForCache(start, key, ttl) {
159
- const pollingTimeout = Math.min(ttl, maxPollingTimeout);
160
- const existing = await __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_redisEntry).call(this, key);
161
- if (existing) {
162
- return existing;
163
- }
164
- if (__classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime() - start.getTime() >= pollingTimeout) {
165
- throw new Error(`Cache request timed out trying to get data at key: ${key}`);
166
- }
167
- await new Promise((resolve) => setTimeout(resolve, pollEvery));
168
- return __classPrivateFieldGet(this, _PromiseCache_instances, "m", _PromiseCache_pollForCache).call(this, start, key, ttl);
169
- }, _PromiseCache_updateCache =
170
- /**
171
- * Actually update the cache. This is the method that will be called if we have the lock.
172
- */
173
- async function _PromiseCache_updateCache(key, entry, closure, ttl) {
174
- const expires = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime() + ttl;
175
- entry = entry ?? {
176
- value: null,
177
- expires,
178
- errorCount: 0,
179
- error: null,
180
- errorTime: null,
181
- checkedAt: 0,
182
- };
183
- try {
184
- entry.value = await closure();
185
- entry.error = null;
186
- entry.errorCount = 0;
187
- entry.errorTime = null;
188
- }
189
- catch (e) {
190
- entry.value = null;
191
- entry.error = e.message ?? 'Unknown error';
192
- entry.errorTime = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime();
193
- entry.errorCount++;
194
- }
195
- __classPrivateFieldGet(this, _PromiseCache_localCache, "f")[key] = entry;
196
- await __classPrivateFieldGet(this, _PromiseCache_redis, "f").set(_namespaced(key), JSON.stringify(entry), {
197
- expiration: new Date(expires + allowStaleFor),
198
- });
199
- /**
200
- * Unlocking will allow retries to happen if there was an error. Otherwise we don't unlock, because the lock
201
- * will expire on its own.
202
- */
203
- if (entry.error && entry.errorCount < retryLimit) {
204
- await __classPrivateFieldGet(this, _PromiseCache_redis, "f").del(_lock(key));
205
- }
206
- return entry;
207
- }, _PromiseCache_calculateRamp = function _PromiseCache_calculateRamp(expiry) {
208
- const now = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime();
209
- const remaining = expiry - now;
210
- if (remaining < 0) {
211
- return 1;
212
- }
213
- else if (remaining < 1000) {
214
- return 0.1;
215
- }
216
- else if (remaining < 2000) {
217
- return 0.01;
218
- }
219
- else if (remaining < 3000) {
220
- return 0.001;
221
- }
222
- else {
223
- return 0;
224
- }
225
- }, _PromiseCache_redisEntry = async function _PromiseCache_redisEntry(key) {
226
- const val = await __classPrivateFieldGet(this, _PromiseCache_redis, "f").get(_namespaced(key));
227
- if (val) {
228
- const entry = JSON.parse(val);
229
- entry.checkedAt = __classPrivateFieldGet(this, _PromiseCache_clock, "f").now().getTime();
230
- __classPrivateFieldGet(this, _PromiseCache_localCache, "f")[key] = entry;
231
- return entry;
232
- }
233
- return undefined;
234
- }, _PromiseCache_enforceTTL = function _PromiseCache_enforceTTL(options) {
235
- if (options.ttl < minTtlValue) {
236
- console.warn(`Cache TTL cannot be less than ${minTtlValue} milliseconds! Updating ttl value of ${options.ttl} to ${minTtlValue}.`);
237
- options.ttl = minTtlValue;
238
- }
239
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"context.test.d.ts","sourceRoot":"","sources":["../../src/types/context.test.ts"],"names":[],"mappings":""}
package/version.json DELETED
@@ -1,75 +0,0 @@
1
- {
2
- "name": "@devvit/public-api",
3
- "version": "0.10.23-dev",
4
- "license": "BSD-3-Clause",
5
- "repository": {
6
- "type": "git",
7
- "url": "https://developers.reddit.com/"
8
- },
9
- "type": "module",
10
- "exports": {
11
- ".": "./dist/index.js",
12
- "./package.json": "./package.json",
13
- "./*": "./dist/*"
14
- },
15
- "main": "./dist/index.js",
16
- "files": [
17
- "dist/**"
18
- ],
19
- "scripts": {
20
- "build": "yarn build:icon-types && yarn build:semantic-colors && tsc && cp -af devvit.tsconfig.json dist/ && yarn build:types && yarn build:min && yarn build:unmin",
21
- "build:icon-types": "make-icons src/types/icons.ts",
22
- "build:min": "esbuild --bundle --sourcemap=linked --target=es2020 --format=esm --metafile=dist/meta.min.json --outfile=dist/public-api.min.js --external:@devvit/protos --minify src/index.ts",
23
- "build:semantic-colors": "node scripts/make-semantic-colors.js",
24
- "build:types": "api-extractor run && sed -ne '/declare global {/,$ p' src/devvit/Devvit.ts >> dist/public-api.d.ts",
25
- "build:unmin": "esbuild --bundle --sourcemap=inline --target=es2020 --format=iife --metafile=dist/meta.json --outfile=dist/public-api.iife.js --global-name=devvitPublicAPI src/index.ts",
26
- "clean": "rm -rf .turbo api-extractor coverage dist src/devvit/internals/semanticColors.ts src/types/icons.ts || :",
27
- "clobber": "yarn clean && rm -rf node_modules",
28
- "dev": "tsc -w",
29
- "dev:build": "chokidar ./src --command 'yarn build' --ignore './src/types/icons.ts' --ignore './src/devvit/internals/semanticColors.ts'",
30
- "lint": "redlint .",
31
- "lint:fix": "yarn lint --fix",
32
- "prepublishOnly": "publish-package-json",
33
- "test": "yarn test:unit && yarn test:types && yarn test:size",
34
- "test:size": "filesize",
35
- "test:types": "tsc --noEmit",
36
- "test:unit": "vitest run",
37
- "test:unit-with-coverage": "vitest run --coverage"
38
- },
39
- "types": "./dist/index.d.ts",
40
- "dependencies": {
41
- "@devvit/protos": "0.10.23-dev",
42
- "@devvit/shared-types": "0.10.23-dev",
43
- "base64-js": "1.5.1",
44
- "clone-deep": "4.0.1",
45
- "core-js": "3.27.2",
46
- "lodash.isequal": "4.5.0"
47
- },
48
- "devDependencies": {
49
- "@ampproject/filesize": "4.3.0",
50
- "@devvit/eslint-config": "0.10.23-dev",
51
- "@devvit/repo-tools": "0.10.23-dev",
52
- "@devvit/tsconfig": "0.10.23-dev",
53
- "@microsoft/api-extractor": "7.41.0",
54
- "@reddit/faceplate-ui": "11.3.3",
55
- "@types/clone-deep": "4.0.1",
56
- "@types/core-js": "2.5.6",
57
- "@types/lodash.isequal": "4.5.6",
58
- "@vitest/coverage-c8": "0.32.0",
59
- "chokidar-cli": "3.0.0",
60
- "esbuild": "0.18.12",
61
- "eslint": "8.9.0",
62
- "typescript": "5.3.2",
63
- "vitest": "1.6.0"
64
- },
65
- "publishConfig": {
66
- "directory": "dist"
67
- },
68
- "filesize": {
69
- "dist/public-api.min.js": {
70
- "gzip": "78 KB",
71
- "none": "255 KB"
72
- }
73
- },
74
- "source": "./src/index.ts"
75
- }