Skip to content

WEBDEV-8507: Migrate field-parsers into elements#51

Open
jbuckner wants to merge 9 commits into
mainfrom
WEBDEV-8507-migrate-field-parsers
Open

WEBDEV-8507: Migrate field-parsers into elements#51
jbuckner wants to merge 9 commits into
mainfrom
WEBDEV-8507-migrate-field-parsers

Conversation

@jbuckner
Copy link
Copy Markdown
Collaborator

@jbuckner jbuckner commented May 27, 2026

Summary

Moves @internetarchive/field-parsers source and tests into src/parsers/ per the conventions established in WEBDEV-8506 / #50. First step in consolidating the metadata-service dependency tree into elements.

Changes

  • src/parsers/field-parser-interface.ts + field-types/*.ts (10 parsers) — straight copy from iaux-field-parsers/src/.
  • src/parsers/timed.ts, trace.ts — debug decorators used by epoch.ts. Brought over for parity; can be retired in a follow-up if unused downstream.
  • src/parsers/field-types/*.test.ts — colocated with sources, ported from Web Test Runner + Mocha + Chai to Vitest. Conversions are mechanical:
    • import { expect } from '@open-wc/testing'import { describe, expect, test } from 'vitest'
    • it()test(), drop the unnecessary async keyword (no awaited operations in any of these tests)
    • expect(x).to.be.true / .false / .undefinedtoBe(true) / toBe(false) / toBeUndefined()
    • to.equal()toBe() (strict equality); to.deep.equal()toEqual()
  • src/parsers/field-types/epoch.ts — two adaptations for elements' stricter tsconfig:
    • enum EpochUnitMultiplierconst EpochUnitMultiplier = {...} as const + matching type alias. Required by erasableSyntaxOnly: true in tsconfig.json (TS 5.8+; enums emit runtime code so they're not erasable).
    • Removed unused trace import (trace2 is used; trace was imported but never referenced). Required by noUnusedLocals: true.

Verification

  • npm run build
  • npm run test ✓ — 211 tests pass, including 70 new tests across the 10 parser types
  • npm run circular ✓ — no new circular deps
  • npm run lint — fails on pre-existing eslint errors in .wireit/ cache (the dist/elements.umd.cjs bundle from the ghpages build). Same failures exist on main; unrelated to this PR.

Order in the migration chain

Test plan

  • Build green
  • All 211 tests pass (including 70 new tests)
  • No circular deps
  • Reviewer: confirm the EpochUnitMultiplier enum → const-object conversion preserves the same value semantics — EpochUnitMultiplier.nanoseconds === 1e-6 etc.
  • Reviewer: confirm the directory layout matches the convention from #50

🤖 Generated with Claude Code

Moves @internetarchive/field-parsers source and tests into
src/parsers/, ported to vitest. EpochUnitMultiplier enum converted
to a const object for erasableSyntaxOnly compatibility; unused
trace import in epoch.ts dropped to satisfy noUnusedLocals.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 27, 2026

PR Preview Action v1.8.1

🚀 View preview at
https://internetarchive.github.io/elements/pr/pr-51/

Built to branch ghpages at 2026-06-01 20:17 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

jbuckner and others added 2 commits May 28, 2026 13:59
The epoch tests built their expected Date with local-timezone setters
(setHours(14)...), which only equals the 1637274397 epoch in
America/Los_Angeles. In CI's UTC environment the expectations were off by
the 8h offset, failing 13/16 tests. Assert against the raw millisecond
values the parser actually produces instead, which is timezone-agnostic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 28, 2026

Codecov Report

❌ Patch coverage is 97.61905% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.69%. Comparing base (9a3b0f3) to head (2fd984d).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
demo/story-template.ts 50.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #51      +/-   ##
==========================================
+ Coverage   78.75%   81.69%   +2.93%     
==========================================
  Files          16       25       +9     
  Lines         645      743      +98     
  Branches      168      203      +35     
==========================================
+ Hits          508      607      +99     
+ Misses         95       90       -5     
- Partials       42       46       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

return this.parseJSDate(rawValue) || this.parseBracketDate(rawValue);
}

// handles "[yyyy]" format
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

QUESTION: Are there any month/year formats we need to support? (BTW: @ximm is a good reference for dates we support throughout the system.)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Potentially? This PR is just for migrating from a standalone repo into elements, not modifying any functionality. I filed https://webarchive.jira.com/browse/WEBDEV-8535 to investigate that.

Copy link
Copy Markdown

@ximm ximm Jun 2, 2026

Choose a reason for hiding this comment

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

QUESTION: Are there any month/year formats we need to support? (BTW: @ximm is a good reference for dates we support throughout the system.)

I can talk about dates, but would need context.

(In brief, forgiving raw string formats with enormous variability and many styles are explicitly allowed in the date field in item metadata; these are normalized in search documents into ISO8601 timestamps, and year derived when possible. Related, I just merged a chance today that will extend the representation of dates in all search documents, to exprsss a range, with a best-effort precision and uncertainty assignment.)

Comment thread src/parsers/field-types/epoch.ts Outdated
for (let i = 0; i < 1e6; i++) {
// EpochParser.secondsParser.parseValue(1637274397); // Example usage of the parser
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

QUESTION: What is this method doing here?

FieldParserRawValue,
} from '../field-parser-interface';

export class ListParser<T> implements FieldParserInterface<T[]> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: It'd be nice if each parser data type listed some example values that it might receive in the comments at the top of the file.

expect(parser.parseValue('movies')).toBe('movies');
expect(parser.parseValue('software')).toBe('software');
expect(parser.parseValue('texts')).toBe('texts');
expect(parser.parseValue('web')).toBe('web');
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

QUESTION: Is this actually a useful set of tests? What if one passed in a value that wasn't in the MediaType set?

Comment thread src/parsers/timed.ts Outdated
@@ -0,0 +1,26 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
export function timed(): (
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Can we be a bit more verbose? I'd think that throughout the code, any non-trivial functions should have doc blocks, explaining what they're for and how to use them. I see a lot fewer in this MR than usual. Anyway, I'd love to know more about the purpose and usage of this function.

jbuckner and others added 6 commits June 1, 2026 12:39
The migration was sourced from the unmerged `epoch` branch of
iaux-field-parsers, which pulled in code absent from that repo's main /
v1.0.0: the EpochParser (plus trace.ts/timed.ts instrumentation only it
used) and a '.' list separator with its own test. Remove all of it and
revert list.ts's separators to [';', ','] so the migrated parsers match
upstream main.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add field-parsers-story.ts, a Lit playground that runs a raw value through
any field-type parser and shows the parsed result and its runtime type.
Extend the demo's story glob to include src/parsers so it's picked up.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Completes the upstream-main alignment: list.ts now uses [';', ','] (the
'.' separator and its period-separated-lists test were migration-time
additions not present in iaux-field-parsers main).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wrap the parser playground in the shared <story-template> chrome for
consistency with the other stories (heading, Demo, Import/Usage/Settings).
Add an optional customImport prop to story-template so non-component
modules (parsers/services/models) can show a correct import snippet, since
the derived `<tag>/<tag>` path only fits custom elements.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… demos

story-template always rendered its heading as `<element-tag>`, which is
misleading for non-component modules (e.g. parsers). Add an optional
`heading` prop that renders as plain text when set, falling back to the
`<tag>` form for actual custom elements. The field-parsers story now uses
heading="Field Parsers".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The sidebar wrapped every story entry in angle brackets, so the parsers
playground showed as `<field-parsers>`. Flag entries from src/elements or
src/labs as components and only bracket those; plain modules (parsers) show
their name as-is.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

4 participants