Skip to content

Feature/fetch#54

Merged
magmacomputing merged 6 commits into
mainfrom
feature/fetch
Jul 6, 2026
Merged

Feature/fetch#54
magmacomputing merged 6 commits into
mainfrom
feature/fetch

Conversation

@magmacomputing

@magmacomputing magmacomputing commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added shorthand mutation/duration unit support, including week-based and abbreviated time keys.
    • Enhanced Tempo.now() to be unit-aware, and added the Tempo.epoch getter.
    • Introduced a new definePlugin registration entry point (with defineExtension marked deprecated).
  • Bug Fixes

    • Improved request utilities with HttpError, better prefix/plain-text vs JSON parsing, and consistent fetchHead failure behavior.
    • Extended duration-like type recognition to accept additional abbreviated unit fields.
  • Chores

    • Bumped package versions to 3.6.0 and refreshed related release notes/docs.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@magmacomputing, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 778711fc-b837-4f79-b4af-f372ccdd4cef

📥 Commits

Reviewing files that changed from the base of the PR and between 06522a2 and 877d176.

📒 Files selected for processing (1)
  • packages/tempo/src/tempo.type.ts
📝 Walkthrough

Walkthrough

This PR updates Tempo’s request helpers and shared utilities, adds shorthand unit support across duration, mutation, and type definitions, renames the plugin factory API to definePlugin, refreshes related docs and changelogs, and bumps package versions to 3.6.0.

Changes

Library Request Helper Rewrite

Layer / File(s) Summary
Request helpers and exports
packages/library/src/common/request.library.ts, packages/library/src/common.index.ts, packages/library/src/server.index.ts, packages/tempo/src/library.index.ts
Adds HttpError, renames the request helpers, changes response parsing and failure handling, and updates the common/server/library re-exports.
Common assertion and loose type updates
packages/library/src/common/assertion.library.ts, packages/library/src/common/type.library.ts
Expands duration-like object checks, adds the deprecation note, and broadens LooseUnion’s generic constraint.
Request and temporal tests
packages/library/test/common/request.library.test.ts, packages/library/test/common/temporal_library.test.ts
Adds request helper coverage for parsing and error behavior, and updates the zone-related temporal assertion.

Tempo Shorthand Units and Epoch Handling

Layer / File(s) Summary
Shorthand enum and type shapes
packages/tempo/src/support/support.enum.ts, packages/tempo/src/tempo.type.ts
Adds ww to the element enum, broadens unit and mutation shorthand types, and updates the mutation-related type aliases.
Duration normalization and parsing
packages/tempo/src/module/module.duration.ts
Normalizes shorthand units in duration conversion, unit parsing, and object remapping.
Mutation shorthand handling
packages/tempo/src/module/module.mutate.ts
Adds wkd validation, updates Slick parsing, and extends add with shorthand unit cases.
Lexer, pattern, and epoch helpers
packages/tempo/src/engine/engine.lexer.ts, packages/tempo/src/engine/engine.pattern.ts, packages/tempo/src/tempo.class.ts
Switches numeric lookup helpers to enum key iterators and updates Tempo.now, epoch getters, and timestamp typing.
Shorthand unit tests
packages/tempo/test/instance/instance.add.test.ts, packages/tempo/test/instance/instance.set.test.ts, packages/tempo/test/instance/instance.since.test.ts, packages/tempo/test/instance/instance.until.test.ts, packages/tempo/test/plugins/plugin_registration.test.ts
Adds test coverage for shorthand keys in add, set, since, until, and plugin initialization.
Shorthand release notes
packages/tempo/CHANGELOG.md
Adds 3.6.0 release notes for shorthand mutation and duration keys.

Plugin API Rename

Layer / File(s) Summary
Plugin factory and deprecations
packages/tempo/src/plugin/plugin.util.ts, packages/tempo/src/plugin/plugin.type.ts
Adds definePlugin, keeps defineExtension as a deprecated wrapper, and marks Extension and TempoExtension as deprecated.
Plugin docs and changelog updates
CHANGELOG.md, packages/tempo/doc/ecosystem.md, packages/tempo/doc/releases/v3.x.md, packages/tempo/doc/tempo.extension.md, packages/tempo/doc/tempo.plugin.md, packages/tempo/doc/tempo.term.md
Updates plugin guides, release notes, and changelog entries to use definePlugin and plugin terminology.

Package Version Bumps

Layer / File(s) Summary
Version bump to 3.6.0
package.json, packages/library/package.json, packages/tempo/package.json, packages/tempo/src/tempo.version.ts
Bumps the root, library, and Tempo package versions, and updates TEMPO_VERSION.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • magmacomputing/magma#29: Both PRs touch packages/library/src/common/assertion.library.ts, modifying the isDurationLike guard.
  • magmacomputing/magma#30: Both PRs change the plugin registration API around defineExtension/definePlugin in packages/tempo/src/plugin/plugin.util.ts.
  • magmacomputing/magma#49: Both PRs modify Slick/shorthand key parsing and wkd handling in packages/tempo/src/module/module.mutate.ts.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is too vague to describe the pull request’s actual changes; it only hints at a fetch-related feature. Use a specific title that names the main change, such as updating request utilities to fetchRequest/fetchHead and adding shorthand mutation support.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/fetch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (4)
packages/library/src/common/request.library.ts (2)

68-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

fetchRequest and fetchHead throw inconsistent error types.

fetchRequest now throws a structured HttpError (status/statusText/body), but fetchHead still throws a plain Error with just the status/statusText message. Since both are part of the same public "request" surface and re-exported together, callers can't uniformly catch/instanceof-check failures across the two helpers.

Consider having fetchHead also throw HttpError for consistency.

Also applies to: 82-93

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/library/src/common/request.library.ts` around lines 68 - 76,
`fetchRequest` and `fetchHead` are throwing different error shapes, so update
`fetchHead` to use the same `HttpError` structure as `fetchRequest`. In the
request helpers in `request.library.ts`, keep the existing
status/statusText/body handling consistent by constructing `HttpError` from the
`fetchHead` failure path instead of a plain `Error`, so callers can reliably
`instanceof`-check both functions’ failures across the shared request API.

50-66: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

JSON detection misses +json structured-syntax suffixes.

contentType.includes('application/json') won't match common JSON media types like application/problem+json, application/vnd.api+json, application/ld+json, etc. (the +json suffix is a registered structured syntax suffix per RFC 6839). Responses using these content types will now be returned as raw strings via res.text() instead of parsed objects, silently changing behavior for callers expecting a parsed object.

🔧 Proposed fix
-				const isJson = contentType.includes('application/json');
+				const isJson = contentType.includes('application/json') || contentType.includes('+json');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/library/src/common/request.library.ts` around lines 50 - 66, Update
the JSON handling in request.library.ts inside the response parsing logic so it
recognizes structured-syntax JSON media types, not just application/json. In the
res.ok branch where contentType and isJson are computed, adjust the detection
used by the config.prefix-free path and the default res.json()/res.text()
selection to treat any Content-Type ending in +json (for example
application/problem+json or application/vnd.api+json) as JSON. Keep the existing
raw-prefix unwrapping behavior in the same request parsing flow and preserve the
current symbols res.ok, config.prefix, and res.headers.get('Content-Type') as
the entry points for the fix.
packages/tempo/src/module/module.duration.ts (1)

84-88: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate duplicated shorthand-unit normalization logic.

The wwweeks / enums.ELEMENT → plural-name mapping is duplicated near-verbatim in three places: balance() (Lines 84-88), duration() (Lines 185-190), and toDuration.toDuration object remapping (Lines 260-272). Any future shorthand-key addition or bugfix must be applied in all three spots, which is easy to miss (e.g. module.mutate.ts also has its own separate unitMap for the same shorthand keys).

♻️ Suggested refactor — extract a shared helper
function resolveElementUnit(key: string): string | undefined {
	if (key === 'ww') return 'weeks';
	if (key in enums.ELEMENT) return `${enums.ELEMENT[key as t.Element]}s`;
	return undefined;
}

Then each call-site applies its own fallback:

-			let temporalUnit = largestUnit;
-			if (temporalUnit === 'ww') temporalUnit = 'weeks';
-			else if (temporalUnit in enums.ELEMENT) temporalUnit = `${enums.ELEMENT[temporalUnit as t.Element]}s`;
+			const temporalUnit = resolveElementUnit(largestUnit) ?? largestUnit;
-	let temporalUnit = unit;
-	if (isDefined(temporalUnit)) {
-		if (temporalUnit === 'ww') temporalUnit = 'weeks';
-		else if (temporalUnit in enums.ELEMENT) temporalUnit = `${enums.ELEMENT[temporalUnit as t.Element]}s`;
-		else temporalUnit = `${singular(temporalUnit)}s`;
-	}
+	let temporalUnit = unit;
+	if (isDefined(temporalUnit))
+		temporalUnit = resolveElementUnit(temporalUnit) ?? `${singular(temporalUnit)}s`;
-			if (k === 'ww') { mappedInput['weeks'] = v; delete mappedInput[k]; }
-			else if (k in enums.ELEMENT) {
-				mappedInput[`${enums.ELEMENT[k as t.Element]}s`] = v;
-				delete mappedInput[k];
-			}
+			const mapped = resolveElementUnit(k);
+			if (mapped) { mappedInput[mapped] = v; delete mappedInput[k]; }

Also applies to: 185-196, 260-272

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tempo/src/module/module.duration.ts` around lines 84 - 88, The
shorthand unit normalization logic is duplicated across balance(), duration(),
and toDuration.toDuration, so extract a shared helper (for example, a resolver
like resolveElementUnit) that maps ww to weeks and enums.ELEMENT keys to plural
names, then have each call site use it with its own fallback behavior. Update
the existing unit normalization branches in those methods to call the shared
helper so future shorthand additions or fixes only need one change.
packages/tempo/src/tempo.type.ts (1)

134-153: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reuse existing numeric range aliases instead of generic number for shorthand fields.

MutateShorthand.yy/mm/dd/hh/mi/ss are typed as string | number, but the file already exports stricter bounded aliases (dd = IntRange<1, 31> at Line 159, and likely similar hh/mi/ss aliases referenced from tempo.class.ts). Using plain number here forfeits compile-time protection against out-of-range literals (e.g. { dd: 99 } would type-check).

♻️ Suggested refactor
 export type MutateShorthand = {
 	yy?: string | number;
-	mm?: string | number;
+	mm?: string | mm;
 	ww?: string;
-	dd?: string | number;
-	hh?: string | number;
-	mi?: string | number;
-	ss?: string | number;
+	dd?: string | dd;
+	hh?: string | hh;
+	mi?: string | mi;
+	ss?: string | ss;
 	ms?: number;
 	us?: number;
 	ns?: number;
 	wkd?: string;
 };

Note: the existing mm = IntRange<0, 12> (Line 158) differs from the readonly mm: IntRange<1, 12> field defined earlier (Line 62); worth reconciling before reusing it here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tempo/src/tempo.type.ts` around lines 134 - 153, MutateShorthand
currently uses broad string | number types for yy/mm/dd/hh/mi/ss, which bypasses
the stricter bounded aliases already defined in this file and elsewhere. Update
MutateShorthand to reuse the existing numeric range aliases (for example dd, and
the corresponding hh/mi/ss aliases from tempo.class.ts) instead of plain number,
and reconcile the mm alias mismatch before wiring it into MutateSet so shorthand
mutation fields keep compile-time range checking.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/library/src/common/assertion.library.ts`:
- Around line 78-80: Normalize shorthand duration keys before the Temporal.add
path by updating Tempo’s `#swap` and/or `#isOptions` flow so shorthand-only objects
accepted by isDurationLike are remapped to Temporal-compatible duration fields
before add is called. Use the existing shorthand mapping behavior from
module.duration and module.mutate as the reference, and ensure new Tempo({ ww: 1
}) or new Tempo({ mi: 5 }) is converted consistently instead of passing
non-Temporal keys through unchanged.

In `@packages/tempo/src/library.index.ts`:
- Line 14: `library.index.ts` currently exposes `fetchRequest` and `fetchHead`
without the `HttpError` type/class that `fetchRequest` can throw, so update this
barrel to re-export `HttpError` as well. Add the missing export alongside the
existing `#library/request.library.js` re-exports so consumers of
`@magmacomputing/tempo` can import and catch `HttpError` from the curated entry
point instead of reaching into `@magmacomputing/library`.

In `@packages/tempo/src/plugin/plugin.util.ts`:
- Around line 175-181: Restore backward compatibility by adding a deprecated
defineExtension alias alongside definePlugin in plugin.util.ts, since
plugin.index.ts re-exports this module and consumers of
`@magmacomputing/tempo/plugin` still expect defineExtension to exist. Keep
definePlugin as the primary implementation, have defineExtension delegate to it
without changing behavior, and mark the alias as deprecated in its documentation
so existing imports continue working on 3.6.0.

---

Nitpick comments:
In `@packages/library/src/common/request.library.ts`:
- Around line 68-76: `fetchRequest` and `fetchHead` are throwing different error
shapes, so update `fetchHead` to use the same `HttpError` structure as
`fetchRequest`. In the request helpers in `request.library.ts`, keep the
existing status/statusText/body handling consistent by constructing `HttpError`
from the `fetchHead` failure path instead of a plain `Error`, so callers can
reliably `instanceof`-check both functions’ failures across the shared request
API.
- Around line 50-66: Update the JSON handling in request.library.ts inside the
response parsing logic so it recognizes structured-syntax JSON media types, not
just application/json. In the res.ok branch where contentType and isJson are
computed, adjust the detection used by the config.prefix-free path and the
default res.json()/res.text() selection to treat any Content-Type ending in
+json (for example application/problem+json or application/vnd.api+json) as
JSON. Keep the existing raw-prefix unwrapping behavior in the same request
parsing flow and preserve the current symbols res.ok, config.prefix, and
res.headers.get('Content-Type') as the entry points for the fix.

In `@packages/tempo/src/module/module.duration.ts`:
- Around line 84-88: The shorthand unit normalization logic is duplicated across
balance(), duration(), and toDuration.toDuration, so extract a shared helper
(for example, a resolver like resolveElementUnit) that maps ww to weeks and
enums.ELEMENT keys to plural names, then have each call site use it with its own
fallback behavior. Update the existing unit normalization branches in those
methods to call the shared helper so future shorthand additions or fixes only
need one change.

In `@packages/tempo/src/tempo.type.ts`:
- Around line 134-153: MutateShorthand currently uses broad string | number
types for yy/mm/dd/hh/mi/ss, which bypasses the stricter bounded aliases already
defined in this file and elsewhere. Update MutateShorthand to reuse the existing
numeric range aliases (for example dd, and the corresponding hh/mi/ss aliases
from tempo.class.ts) instead of plain number, and reconcile the mm alias
mismatch before wiring it into MutateSet so shorthand mutation fields keep
compile-time range checking.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 983064ea-f60e-4627-8299-8d68510a489d

📥 Commits

Reviewing files that changed from the base of the PR and between 5832b73 and 11316f0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (29)
  • CHANGELOG.md
  • package.json
  • packages/library/package.json
  • packages/library/src/common.index.ts
  • packages/library/src/common/assertion.library.ts
  • packages/library/src/common/request.library.ts
  • packages/library/src/server.index.ts
  • packages/library/test/common/request.library.test.ts
  • packages/library/test/common/temporal_library.test.ts
  • packages/tempo/CHANGELOG.md
  • packages/tempo/doc/ecosystem.md
  • packages/tempo/doc/releases/v3.x.md
  • packages/tempo/doc/tempo.extension.md
  • packages/tempo/doc/tempo.plugin.md
  • packages/tempo/doc/tempo.term.md
  • packages/tempo/package.json
  • packages/tempo/src/library.index.ts
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/module/module.mutate.ts
  • packages/tempo/src/plugin/plugin.type.ts
  • packages/tempo/src/plugin/plugin.util.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
  • packages/tempo/src/tempo.version.ts
  • packages/tempo/test/instance/instance.add.test.ts
  • packages/tempo/test/instance/instance.set.test.ts
  • packages/tempo/test/instance/instance.since.test.ts
  • packages/tempo/test/instance/instance.until.test.ts
  • packages/tempo/test/plugins/plugin_registration.test.ts
💤 Files with no reviewable changes (1)
  • packages/library/src/server.index.ts

Comment thread packages/library/src/common/assertion.library.ts
Comment thread packages/tempo/src/library.index.ts Outdated
Comment thread packages/tempo/src/plugin/plugin.util.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/tempo/src/tempo.type.ts`:
- Around line 134-151: `MutateShorthand` is missing the supported `wy` week key,
so update that type to expose `wy` alongside `ww` using the existing
`LooseUnion<wy>` pattern already used for the other shorthand fields. Keep the
change localized in `MutateShorthand` so `MutateSet` automatically picks up the
new key through its existing intersection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 044aa76e-0570-44f0-a85a-7050c45d72a1

📥 Commits

Reviewing files that changed from the base of the PR and between 11316f0 and 06522a2.

📒 Files selected for processing (12)
  • packages/library/src/common/request.library.ts
  • packages/library/src/common/type.library.ts
  • packages/tempo/CHANGELOG.md
  • packages/tempo/src/engine/engine.lexer.ts
  • packages/tempo/src/engine/engine.pattern.ts
  • packages/tempo/src/library.index.ts
  • packages/tempo/src/module/module.duration.ts
  • packages/tempo/src/module/module.mutate.ts
  • packages/tempo/src/plugin/plugin.util.ts
  • packages/tempo/src/support/support.enum.ts
  • packages/tempo/src/tempo.class.ts
  • packages/tempo/src/tempo.type.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/tempo/src/library.index.ts
  • packages/tempo/src/tempo.class.ts
  • packages/library/src/common/request.library.ts
  • packages/tempo/src/module/module.mutate.ts

Comment thread packages/tempo/src/tempo.type.ts
@magmacomputing magmacomputing merged commit 9a2fa96 into main Jul 6, 2026
2 checks passed
@magmacomputing magmacomputing deleted the feature/fetch branch July 6, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant