{"version":3,"file":"bundleAssetPolicy.cjs","names":["BUNDLE_ASSET_POLICY_VERSION","BUNDLE_ASSET_POLICY_PATH"],"sources":["../../../src/builders/web/bundleAssetPolicy.ts"],"sourcesContent":["import {\n  BUNDLE_ASSET_POLICY_PATH,\n  BUNDLE_ASSET_POLICY_VERSION,\n  type BundleAssetPolicy,\n} from '@agimon-ai/doompi-core/bundle-asset-policy';\nimport type { Plugin } from 'vite';\n\nconst OPTIONAL_PACKAGES = ['/node_modules/mermaid/', '/node_modules/pdfjs-dist/'] as const;\n\ninterface PolicyOutput {\n  type: 'asset' | 'chunk';\n  isEntry?: boolean;\n  facadeModuleId?: string | null;\n  modules?: Record<string, unknown>;\n  imports?: string[];\n  dynamicImports?: string[];\n  referencedFiles?: string[];\n  code?: string;\n  source?: string | Uint8Array;\n  viteMetadata?: { importedAssets?: Set<string> };\n}\n\nfunction packageOwner(output: PolicyOutput, owned: ReadonlyMap<string, ReadonlySet<string>>): string | undefined {\n  const ids = Object.keys(output.modules ?? {});\n  return OPTIONAL_PACKAGES.find(\n    (dependency) =>\n      ids.some((id) => id.replaceAll('\\\\', '/').includes(dependency)) &&\n      ids.every((id) => owned.get(dependency)?.has(id)),\n  );\n}\n\nfunction references(output: PolicyOutput): string[] {\n  if (output.type === 'asset') return [];\n  return [\n    ...(output.imports ?? []),\n    ...(output.dynamicImports ?? []),\n    ...(output.referencedFiles ?? []),\n    ...(output.viteMetadata?.importedAssets ?? []),\n  ];\n}\n\n/** Classifies only output owned exclusively by a known optional dependency graph. */\nexport function classifyOptionalBundleAssets(\n  bundle: Readonly<Record<string, PolicyOutput>>,\n  moduleDependencies?: (id: string) => readonly string[] | undefined,\n): string[] {\n  const outputs = new Map(Object.entries(bundle));\n  const owned = new Map<string, Set<string>>();\n  for (const dependency of OPTIONAL_PACKAGES) {\n    const modules = new Set<string>();\n    const visit = (id: string): void => {\n      // Application and unresolved virtual modules never inherit optional ownership.\n      if (modules.has(id) || !id.replaceAll('\\\\', '/').includes('/node_modules/')) return;\n      modules.add(id);\n      for (const imported of moduleDependencies?.(id) ?? []) visit(imported);\n    };\n    for (const output of outputs.values()) {\n      for (const id of Object.keys(output.modules ?? {})) {\n        if (id.replaceAll('\\\\', '/').includes(dependency)) visit(id);\n      }\n    }\n    owned.set(dependency, modules);\n  }\n  const graphReferences = (output: PolicyOutput): string[] => {\n    const source =\n      output.code ??\n      (typeof output.source === 'string'\n        ? output.source\n        : output.source === undefined\n          ? ''\n          : new TextDecoder().decode(output.source));\n    return [\n      ...references(output),\n      ...[...outputs]\n        .filter(([fileName, candidate]) => candidate.type === 'asset' && source.includes(fileName))\n        .map(([fileName]) => fileName),\n    ];\n  };\n  const optionalRoots = new Map<string, string>();\n  for (const [fileName, output] of outputs) {\n    if (output.type !== 'chunk') continue;\n    const owner = packageOwner(output, owned);\n    const facade = output.facadeModuleId?.replaceAll('\\\\', '/');\n    if (\n      owner !== undefined &&\n      (!output.isEntry || OPTIONAL_PACKAGES.some((dependency) => facade?.includes(dependency)))\n    ) {\n      optionalRoots.set(fileName, owner);\n    }\n  }\n\n  const eager = new Set<string>();\n  const visitEager = (fileName: string): void => {\n    if (eager.has(fileName)) return;\n    eager.add(fileName);\n    const output = outputs.get(fileName);\n    if (output === undefined) return;\n    for (const reference of graphReferences(output)) {\n      const deferredRoot = optionalRoots.has(reference) && output.dynamicImports?.includes(reference);\n      if (!deferredRoot) visitEager(reference);\n    }\n  };\n  for (const [fileName, output] of outputs) {\n    if (fileName === 'index.html' || (output.type === 'chunk' && output.isEntry && !optionalRoots.has(fileName)))\n      visitEager(fileName);\n  }\n\n  const optional = new Set<string>();\n  const visitOptional = (fileName: string, owner: string): void => {\n    if (eager.has(fileName) || optional.has(fileName)) return;\n    const output = outputs.get(fileName);\n    if (output === undefined) return;\n    if (output.type === 'chunk') {\n      const ids = Object.keys(output.modules ?? {});\n      if (ids.length === 0 || !ids.every((id) => owned.get(owner)?.has(id))) {\n        visitEager(fileName);\n        return;\n      }\n    }\n    optional.add(fileName);\n    for (const reference of graphReferences(output)) {\n      const referencedRootOwner = optionalRoots.get(reference);\n      if (referencedRootOwner === undefined || referencedRootOwner === owner) visitOptional(reference, owner);\n    }\n  };\n  for (const [fileName, owner] of optionalRoots) visitOptional(fileName, owner);\n  return [...optional]\n    .filter((fileName) => !eager.has(fileName) && !fileName.endsWith('.map'))\n    .map((fileName) => `/${fileName}`)\n    .sort();\n}\n\n/** Emits an authenticated v1 policy derived from Rollup's module and resource graph. */\nexport function bundleAssetPolicyPlugin(): Plugin {\n  return {\n    name: 'doompi-bundle-asset-policy',\n    generateBundle(_options, bundle) {\n      const policy: BundleAssetPolicy = {\n        version: BUNDLE_ASSET_POLICY_VERSION,\n        optional: classifyOptionalBundleAssets(bundle, (id) => {\n          const info = this.getModuleInfo(id);\n          return info === null ? undefined : [...info.importedIds, ...info.dynamicallyImportedIds];\n        }),\n      };\n      this.emitFile({\n        type: 'asset',\n        fileName: BUNDLE_ASSET_POLICY_PATH.slice(1),\n        source: `${JSON.stringify(policy)}\\n`,\n      });\n    },\n  };\n}\n"],"mappings":"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"}