@ultimat3/http 30.3.0 → 30.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/http",
3
- "version": "30.3.0",
3
+ "version": "30.5.0",
4
4
  "description": "Owned request lifecycle over Bun.serve: router, ordered pipeline, problem+json errors",
5
5
  "keywords": [
6
6
  "ultimate",
@@ -45,9 +45,9 @@
45
45
  "test": "bun test"
46
46
  },
47
47
  "dependencies": {
48
- "@ultimat3/core": "30.3.0",
49
- "@ultimat3/i18n": "30.3.0",
50
- "@ultimat3/schema": "30.3.0",
51
- "@ultimat3/time": "30.3.0"
48
+ "@ultimat3/core": "30.5.0",
49
+ "@ultimat3/i18n": "30.5.0",
50
+ "@ultimat3/schema": "30.5.0",
51
+ "@ultimat3/time": "30.5.0"
52
52
  }
53
53
  }
package/src/index.ts CHANGED
@@ -188,6 +188,7 @@ export {
188
188
  installedRateLimitStore,
189
189
  installRateLimitStore,
190
190
  resetRateLimitStore,
191
+ withScratchRateLimitStore,
191
192
  } from './rate-limit-installed';
192
193
  export type { RateLimitPeek } from './rate-limit-peek';
193
194
  export { rateLimitPeek, refilledTokens } from './rate-limit-peek';
@@ -77,3 +77,24 @@ export const assertInstalledRateLimitScope = (config: RateLimitConfig): void =>
77
77
  if (config.scope !== 'shared') return;
78
78
  if (current().scope !== 'shared') throw rateLimitNotShared('installed');
79
79
  };
80
+
81
+ /**
82
+ * `fn` spending from a fresh store of its own, the installed one left exactly as it was — the
83
+ * contract exercise's runs (`@ultimat3/action`, `@ultimat3/query`): a test-time loop that must not
84
+ * leave the same file's next call a 429. It answers for the installed store's scope, so a
85
+ * `'shared'` declaration is still judged against what the app installed, not the scratch.
86
+ */
87
+ export async function withScratchRateLimitStore<T>(fn: () => Promise<T>): Promise<T> {
88
+ const scratch = memoryRateLimitStore();
89
+ const release = adoptRateLimitStore({
90
+ scope: current().scope,
91
+ take: (key, bucket, cost, nowMs) => scratch.take(key, bucket, cost, nowMs),
92
+ peek: (key, bucket, nowMs) => scratch.peek(key, bucket, nowMs),
93
+ reset: (key) => scratch.reset(key),
94
+ });
95
+ try {
96
+ return await fn();
97
+ } finally {
98
+ release();
99
+ }
100
+ }