Skip to content

feat: ScriptManager hook system#1078

Merged
jbroma merged 42 commits intomainfrom
feat/script-manager-hooks
Apr 9, 2025
Merged

feat: ScriptManager hook system#1078
jbroma merged 42 commits intomainfrom
feat/script-manager-hooks

Conversation

@szymonrybczak
Copy link
Copy Markdown
Contributor

@szymonrybczak szymonrybczak commented Mar 10, 2025

Summary

This PR introduces a powerful hook system to ScriptManager that allows developers to intercept and customize the script loading process at various stages. The hooks provide fine-grained control over script resolution and loading, enabling advanced use cases like custom caching strategies, script transformation, and error handling.

Available Hooks

The following hooks are now available on ScriptManager.shared.hooks:

  1. Resolution Hooks

    • beforeResolve: called before script resolution begins, allows you to modify the arguments of a resolution request
    • resolve: customise / override the script resolution process
    • afterResolve: modify the resolved script locator after resolution succeeds
    • errorResolve: provide a fallback for resolution request when normal resolution fails
  2. Loading Hooks

    • beforeLoad: called before script loading begins, allows you to modify the arguments of a loading request
    • load: customise / override the script resolution process
    • afterLoad: react to successful script loading event
    • errorLoad: provide a fallback for a script when normal loading procedure fails

Usage Examples

Basic Hook Setup

ScriptManager.shared.hooks.beforeResolve(async (args) => {
  console.debug('ScriptManager.shared.hooks.beforeResolve', args);
  return args;
});

ScriptManager.shared.hooks.resolve(async (args) => {
  console.debug('ScriptManager.shared.hooks.resolve', args);
  const { scriptId, caller, referenceUrl } = args.options;
  for (const [, , resolve] of args.resolvers) {
    const locator = await resolve(scriptId, caller, referenceUrl);
    if (locator) return locator;
  }
});

ScriptManager.shared.hooks.afterResolve(async (args) => {
  console.debug('ScriptManager.shared.hooks.afterResolve', args);
  return args;
});

ScriptManager.shared.hooks.beforeLoad(async (args) => {
  console.debug('ScriptManager.shared.hooks.beforeLoad', args);
  return args;
});

ScriptManager.shared.hooks.load(async (args) => {
  console.debug('ScriptManager.shared.hooks.load', args);
  await args.loadScript();
  return true;
});

ScriptManager.shared.hooks.afterLoad(async (args) => {
  console.debug('ScriptManager.shared.hooks.afterLoad', args);
  return args;
});

Advanced Use Cases

  1. Custom Caching Strategy
ScriptManager.shared.hooks.afterResolve(async (args) => {
  const { locator, options } = args;
  // Implement custom caching logic
  if (shouldCache(locator)) {
    locator.cache = true;
  }
  return args;
});
  1. Script Transformation
ScriptManager.shared.hooks.beforeLoad(async (args) => {
  const { script } = args;
  // Transform script before loading
  script.locator.url = transformUrl(script.locator.url);
  return args;
});
  1. Error Handling
ScriptManager.shared.hooks.errorLoad(async (args) => {
  const { error, options } = args;
  // Implement custom error handling
  if (isRecoverableError(error)) {
    await retryLoading(options);
    return true;
  }
  return false;
});

Migration Guide

No migration is required for existing code. The hooks system is additive and doesn't break existing functionality. The default behavior remains unchanged unless hooks are explicitly added.

Additional Notes

  • The hook system is built on top of the tapable library for reliable async hook execution
  • Hooks can be used in combination with existing event listeners
  • Each hook is fully typed with TypeScript for better development experience

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 10, 2025

🦋 Changeset detected

Latest commit: 448447d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@callstack/repack Major
@callstack/repack-plugin-expo-modules Major
@callstack/repack-plugin-nativewind Major
@callstack/repack-plugin-reanimated Major
@callstack/repack-dev-server Major
@callstack/repack-init Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 10, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
repack-docs-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 9, 2025 2:40pm
repack-docs-v3 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 9, 2025 2:40pm
repack-docs-v4 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 9, 2025 2:40pm
repack-website ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 9, 2025 2:40pm

@jbroma jbroma changed the title feat: initial version of ScriptManager tapable hooks feat: ScriptManager hook system Apr 9, 2025
@jbroma jbroma merged commit 5ac48cd into main Apr 9, 2025
5 checks passed
@jbroma jbroma deleted the feat/script-manager-hooks branch April 9, 2025 14:45
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.

2 participants