Skip to content

Web shims are missing 10 exports; four break user actions on Web #74

Description

@kmch4n

Summary

#71 fixed one .web shim that had drifted from the module it stands in for. Diffing every native/.web pair afterwards shows it was not an isolated slip: 10 more exports are missing across five shims, and four of them are reachable from screens that have no .web companion, so they fail the same way — TypeError: x is not a function, only at the moment the user triggers the action.

Filing separately rather than widening #71, which is closed.

The gap

Measured on bcddff2:

shim exports missing relative to the native module
src/database/repositories/videoRepository.web.ts bulkSetFavorite, deleteVideos, getExistingAssetIds, getVideosWithSuspiciousCapturedAt, updateVideoThumbnailUri
src/database/repositories/tagRepository.web.ts deleteCustomTag
src/database/repositories/techniqueOptionRepository.web.ts reorderTechniqueOptions
src/services/managedVideoFileService.web.ts getManagedVideoDirectoryUri
src/services/thumbnailService.web.ts getThumbnailDirectoryUri

Which of these actually break

Traced each importer and checked whether it has a .web variant of its own. Only the ones without can reach the shim.

Reachable on Web — these are live bugs:

export importer without a .web companion user-visible action
deleteVideos src/app/(tabs)/index/index.tsx, src/app/settings/duplicate-candidates.tsx, src/services/videoDeletionService.ts bulk delete from home, delete from duplicate candidates
bulkSetFavorite src/app/(tabs)/index/index.tsx bulk favourite from home
deleteCustomTag src/app/settings/tags.tsx delete a custom tag
reorderTechniqueOptions src/app/settings/techniques.tsx drag to reorder techniques

deleteVideos is the worst of the four: it is the same bulk-delete path #71 was about, so that path is still broken on Web even after isSyntheticAssetId was fixed.

Not reachable — every importer resolves to its own .web file, so the native module never loads:

getExistingAssetIds (video-import.tsx), getVideosWithSuspiciousCapturedAt (_layout.tsx), updateVideoThumbnailUri (thumbnailMigrationService.ts), getManagedVideoDirectoryUri and getThumbnailDirectoryUri (orphanedFileCleanupService.ts, importService.ts).

These are still worth closing for consistency — today's safe gap becomes tomorrow's bug the moment a new caller lacks a .web file — but they are not urgent.

Why nothing catches this

npx tsc --noEmit is clean. TypeScript resolves ./videoRepository to videoRepository.ts, which does export everything. Only Metro substitutes the .web variant at bundle time, so the type checker never compares the two files. npm run lint does not compare them either.

The failure is also silent until the exact moment of use: all four live cases sit in callbacks, so the screen renders normally and the throw lands on the user's click.

Suggested approach

  1. Fill the four reachable gaps first — they are user-visible.
  2. Fill the remaining five for parity.
  3. Add a mechanical check so the next drift is caught rather than discovered. A node:test case fits the existing scripts/tests/ setup and needs no new tooling — it can compare exported names by reading both files, with no compilation:
for f in src/database/repositories/*.ts src/services/*.ts; do
    case "$f" in *.web.ts) continue;; esac
    w="${f%.ts}.web.ts"; [ -f "$w" ] || continue
    diff <(grep -oE "^export (async )?function [a-zA-Z]+" "$f" | grep -oE "[a-zA-Z]+$" | sort) \
         <(grep -oE "^export (async )?function [a-zA-Z]+" "$w" | grep -oE "[a-zA-Z]+$" | sort)
done

Note this shell version only sees export function / export async function declarations. A test should also handle export const and export { ... } from, which is how mediaService.ts exposes isSyntheticAssetId after #71 — a checker that missed re-exports would report a false positive there.

Acceptance criteria

  • Every .web shim exports at least what its native counterpart does.
  • Bulk delete, bulk favourite, custom-tag delete and technique reorder all work on Web without a TypeError.
  • A check fails when a native module gains an export its .web shim lacks, and it understands re-exports.
  • Native behaviour is unchanged.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:webWeb-specific behavior and stubsbugSomething isn't workingpriority:lowLow prioritytech-debtCode health and maintainability

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions