one 2.11.5 → 2.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/margelo/nitro/one/HybridOneAudio.kt +309 -124
- package/dist/cjs/cli/build.cjs +31 -33
- package/dist/cjs/cli/build.native.cjs +31 -33
- package/dist/cjs/cli/build.native.js +31 -33
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.cjs +11 -7
- package/dist/cjs/cli/buildPage.native.cjs +11 -7
- package/dist/cjs/cli/buildPage.native.js +11 -7
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/cli/buildPageWorker.cjs +1 -1
- package/dist/cjs/cli/buildPageWorker.native.cjs +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js.map +1 -1
- package/dist/cjs/cli-dev-memory.cjs +43 -0
- package/dist/cjs/cli-dev-memory.native.cjs +84 -0
- package/dist/cjs/cli-dev-memory.native.js +86 -0
- package/dist/cjs/cli-dev-memory.native.js.map +1 -0
- package/dist/cjs/headless-server.cjs +2 -5
- package/dist/cjs/headless-server.native.cjs +2 -5
- package/dist/cjs/headless-server.native.js +2 -5
- package/dist/cjs/headless-server.native.js.map +1 -1
- package/dist/cjs/platform/audio/index.cjs +83 -76
- package/dist/cjs/platform/audio/index.native.cjs +2 -2
- package/dist/cjs/platform/audio/index.native.js +2 -2
- package/dist/cjs/platform/audio/index.native.js.map +1 -1
- package/dist/cjs/platform/audio/nowPlaying.cjs +126 -0
- package/dist/cjs/platform/audio/nowPlaying.native.cjs +160 -0
- package/dist/cjs/platform/audio/nowPlaying.native.js +162 -0
- package/dist/cjs/platform/audio/nowPlaying.native.js.map +1 -0
- package/dist/cjs/platform/audio/player.cjs +15 -0
- package/dist/cjs/platform/audio/player.native.cjs +14 -0
- package/dist/cjs/platform/audio/player.native.js +14 -0
- package/dist/cjs/platform/audio/player.native.js.map +1 -1
- package/dist/cjs/platform/audio/unavailable.cjs +1 -1
- package/dist/cjs/platform/audio/unavailable.native.cjs +1 -1
- package/dist/cjs/platform/audio/unavailable.native.js +1 -1
- package/dist/cjs/platform/audio/unavailable.native.js.map +1 -1
- package/dist/cjs/serve-worker.cjs +0 -3
- package/dist/cjs/serve-worker.native.cjs +0 -3
- package/dist/cjs/serve-worker.native.js +0 -3
- package/dist/cjs/serve-worker.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +0 -6
- package/dist/cjs/server/oneServe.native.cjs +0 -6
- package/dist/cjs/server/oneServe.native.js +0 -6
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/server/workerHandler.cjs +12 -10
- package/dist/cjs/server/workerHandler.native.cjs +14 -10
- package/dist/cjs/server/workerHandler.native.js +14 -10
- package/dist/cjs/server/workerHandler.native.js.map +1 -1
- package/dist/cjs/vite/plugins/workerdDevPlugin.cjs +33 -37
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.cjs +33 -37
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.js +33 -37
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.js.map +1 -1
- package/dist/esm/cli/build.mjs +31 -33
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +31 -33
- package/dist/esm/cli/build.native.js.map +1 -1
- package/dist/esm/cli/buildPage.mjs +11 -7
- package/dist/esm/cli/buildPage.mjs.map +1 -1
- package/dist/esm/cli/buildPage.native.js +11 -7
- package/dist/esm/cli/buildPage.native.js.map +1 -1
- package/dist/esm/cli/buildPageWorker.mjs +1 -1
- package/dist/esm/cli/buildPageWorker.mjs.map +1 -1
- package/dist/esm/cli/buildPageWorker.native.js +1 -1
- package/dist/esm/cli/buildPageWorker.native.js.map +1 -1
- package/dist/esm/cli-dev-memory.mjs +23 -0
- package/dist/esm/cli-dev-memory.mjs.map +1 -0
- package/dist/esm/cli-dev-memory.native.js +62 -0
- package/dist/esm/cli-dev-memory.native.js.map +1 -0
- package/dist/esm/headless-server.mjs +2 -3
- package/dist/esm/headless-server.mjs.map +1 -1
- package/dist/esm/headless-server.native.js +2 -3
- package/dist/esm/headless-server.native.js.map +1 -1
- package/dist/esm/platform/audio/index.mjs +83 -76
- package/dist/esm/platform/audio/index.mjs.map +1 -1
- package/dist/esm/platform/audio/index.native.js +2 -2
- package/dist/esm/platform/audio/index.native.js.map +1 -1
- package/dist/esm/platform/audio/nowPlaying.mjs +102 -0
- package/dist/esm/platform/audio/nowPlaying.mjs.map +1 -0
- package/dist/esm/platform/audio/nowPlaying.native.js +134 -0
- package/dist/esm/platform/audio/nowPlaying.native.js.map +1 -0
- package/dist/esm/platform/audio/player.mjs +15 -0
- package/dist/esm/platform/audio/player.mjs.map +1 -1
- package/dist/esm/platform/audio/player.native.js +14 -0
- package/dist/esm/platform/audio/player.native.js.map +1 -1
- package/dist/esm/platform/audio/unavailable.mjs +1 -1
- package/dist/esm/platform/audio/unavailable.mjs.map +1 -1
- package/dist/esm/platform/audio/unavailable.native.js +1 -1
- package/dist/esm/platform/audio/unavailable.native.js.map +1 -1
- package/dist/esm/serve-worker.mjs +1 -2
- package/dist/esm/serve-worker.mjs.map +1 -1
- package/dist/esm/serve-worker.native.js +1 -2
- package/dist/esm/serve-worker.native.js.map +1 -1
- package/dist/esm/server/oneServe.mjs +0 -6
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +0 -6
- package/dist/esm/server/oneServe.native.js.map +1 -1
- package/dist/esm/server/workerHandler.mjs +12 -10
- package/dist/esm/server/workerHandler.mjs.map +1 -1
- package/dist/esm/server/workerHandler.native.js +14 -10
- package/dist/esm/server/workerHandler.native.js.map +1 -1
- package/dist/esm/vite/plugins/workerdDevPlugin.mjs +33 -37
- package/dist/esm/vite/plugins/workerdDevPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/workerdDevPlugin.native.js +33 -37
- package/dist/esm/vite/plugins/workerdDevPlugin.native.js.map +1 -1
- package/ios/Nitro/HybridOneAudio.swift +309 -96
- package/nitrogen/generated/android/c++/JAudioPlayOptions.hpp +61 -0
- package/nitrogen/generated/android/c++/JAudioRemoteCommandEvent.hpp +8 -3
- package/nitrogen/generated/android/c++/JFunc_void_AudioRemoteCommandEvent.hpp +1 -0
- package/nitrogen/generated/android/c++/JHybridOneAudioSpec.cpp +37 -3
- package/nitrogen/generated/android/c++/JHybridOneAudioSpec.hpp +3 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/AudioPlayOptions.kt +56 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/AudioRemoteCommandEvent.kt +9 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/one/HybridOneAudioSpec.kt +40 -32
- package/nitrogen/generated/ios/One-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridOneAudioSpecSwift.hpp +21 -2
- package/nitrogen/generated/ios/swift/AudioPlayOptions.swift +60 -0
- package/nitrogen/generated/ios/swift/AudioRemoteCommandEvent.swift +19 -1
- package/nitrogen/generated/ios/swift/HybridOneAudioSpec.swift +3 -1
- package/nitrogen/generated/ios/swift/HybridOneAudioSpec_cxx.swift +70 -32
- package/nitrogen/generated/shared/c++/AudioPlayOptions.hpp +87 -0
- package/nitrogen/generated/shared/c++/AudioRemoteCommandEvent.hpp +7 -2
- package/nitrogen/generated/shared/c++/HybridOneAudioSpec.cpp +2 -0
- package/nitrogen/generated/shared/c++/HybridOneAudioSpec.hpp +6 -1
- package/package.json +13 -13
- package/run.mjs +5 -1
- package/src/cli/build.ts +35 -32
- package/src/cli/buildPage.test.ts +152 -0
- package/src/cli/buildPage.ts +14 -9
- package/src/cli/buildPageWorker.ts +2 -1
- package/src/cli/workerPool.ts +1 -0
- package/src/cli-dev-memory.ts +24 -0
- package/src/headless-server.ts +2 -2
- package/src/index.ts +1 -0
- package/src/platform/audio/index.native.ts +4 -2
- package/src/platform/audio/index.ts +102 -74
- package/src/platform/audio/nowPlaying.ts +122 -0
- package/src/platform/audio/player.native.ts +17 -1
- package/src/platform/audio/player.ts +23 -1
- package/src/platform/audio/types.ts +6 -1
- package/src/platform/audio/unavailable.ts +3 -1
- package/src/platform/index.native.ts +1 -0
- package/src/platform/index.ts +1 -0
- package/src/platform/specs/OneAudio.nitro.ts +11 -1
- package/src/serve-worker.ts +2 -3
- package/src/server/oneServe.ts +0 -6
- package/src/server/workerHandler.ts +34 -18
- package/src/vite/plugins/workerdDevPlugin.ts +33 -37
- package/src/vite/resolveResponse.ts +2 -2
- package/types/cli/build.d.ts.map +1 -1
- package/types/cli/buildPage.d.ts +1 -1
- package/types/cli/buildPage.d.ts.map +1 -1
- package/types/cli/workerPool.d.ts +1 -0
- package/types/cli/workerPool.d.ts.map +1 -1
- package/types/cli-dev-memory.d.ts +2 -0
- package/types/cli-dev-memory.d.ts.map +1 -0
- package/types/headless-server.d.ts +3 -3
- package/types/headless-server.d.ts.map +1 -1
- package/types/index.d.ts +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/platform/audio/index.d.ts +2 -2
- package/types/platform/audio/index.d.ts.map +1 -1
- package/types/platform/audio/index.native.d.ts +3 -3
- package/types/platform/audio/index.native.d.ts.map +1 -1
- package/types/platform/audio/nowPlaying.d.ts +12 -0
- package/types/platform/audio/nowPlaying.d.ts.map +1 -0
- package/types/platform/audio/player.d.ts +3 -1
- package/types/platform/audio/player.d.ts.map +1 -1
- package/types/platform/audio/player.native.d.ts +3 -1
- package/types/platform/audio/player.native.d.ts.map +1 -1
- package/types/platform/audio/types.d.ts +3 -1
- package/types/platform/audio/types.d.ts.map +1 -1
- package/types/platform/audio/unavailable.d.ts +3 -3
- package/types/platform/audio/unavailable.d.ts.map +1 -1
- package/types/platform/index.d.ts +1 -1
- package/types/platform/index.d.ts.map +1 -1
- package/types/platform/index.native.d.ts +1 -1
- package/types/platform/index.native.d.ts.map +1 -1
- package/types/platform/specs/OneAudio.nitro.d.ts +8 -1
- package/types/platform/specs/OneAudio.nitro.d.ts.map +1 -1
- package/types/serve-worker.d.ts +3 -3
- package/types/serve-worker.d.ts.map +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/server/workerHandler.d.ts +1 -1
- package/types/server/workerHandler.d.ts.map +1 -1
- package/types/vite/plugins/workerdDevPlugin.d.ts.map +1 -1
- package/types/vite/resolveResponse.d.ts +1 -1
- package/types/vite/resolveResponse.d.ts.map +1 -1
- package/dist/cjs/server/staticHtmlFetcher.cjs +0 -33
- package/dist/cjs/server/staticHtmlFetcher.native.cjs +0 -35
- package/dist/cjs/server/staticHtmlFetcher.native.js +0 -37
- package/dist/cjs/server/staticHtmlFetcher.native.js.map +0 -1
- package/dist/esm/server/staticHtmlFetcher.mjs +0 -10
- package/dist/esm/server/staticHtmlFetcher.mjs.map +0 -1
- package/dist/esm/server/staticHtmlFetcher.native.js +0 -10
- package/dist/esm/server/staticHtmlFetcher.native.js.map +0 -1
- package/src/server/staticHtmlFetcher.ts +0 -12
- package/types/server/staticHtmlFetcher.d.ts +0 -3
- package/types/server/staticHtmlFetcher.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workerdDevPlugin.native.js","names":[],"sources":["esm/vite/plugins/workerdDevPlugin.native.js"],"sourcesContent":["import { mkdirSync, writeFileSync } from \"fs\";\nimport { join, resolve } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport { resolvePath } from \"@vxrn/resolve\";\nimport { cloudflare } from \"@cloudflare/vite-plugin\";\nimport { getPlatformEnvDefine } from \"@vxrn/utils\";\nimport { exactRegex } from \"rolldown/filter\";\nimport { CACHE_KEY } from \"../../constants\";\nimport { virtalEntryIdClient, virtualEntryId } from \"./virtualEntryConstants\";\nimport { getManifest } from \"../getManifest\";\nimport { getRouterRootFromOneOptions } from \"../../utils/getRouterRootFromOneOptions\";\nimport { absorbedPackageAliases } from \"../../utils/absorbedPackages\";\nimport { createCloudflareWranglerConfig, getCloudflareProjectNameSync, loadUserWranglerConfigSync, shouldEnableWorkerdDev } from \"../cloudflareWranglerConfig\";\nvar workerdDevEntryId = \"virtual:one-workerd-dev-entry\";\nvar resolvedWorkerdDevEntryId = `\\0${workerdDevEntryId}`;\nvar WORKERD_DEV_DIR = \"node_modules/.one-workerd-dev\";\nfunction serveOnly(plugin) {\n var existing = plugin.apply;\n return {\n ...plugin,\n apply(config, env) {\n if (env.command !== \"serve\") return false;\n if (typeof existing === \"function\") return existing(config, env);\n if (existing === \"build\") return false;\n return true;\n }\n };\n}\nfunction toImportHref(root, routerRoot, routeFile) {\n var rel = routeFile.replace(/^\\.\\//, \"\");\n return pathToFileURL(resolve(root, routerRoot, rel)).href;\n}\nfunction serializeImportMap(entries) {\n return entries.map(function(param) {\n var [key, href] = param;\n return ` ${JSON.stringify(key)}: () => import(${JSON.stringify(href)})`;\n }).join(\",\\n\");\n}\nfunction stripRouteForWorker(route) {\n var { layouts, middlewares, ...rest } = route;\n return {\n ...rest,\n // live-render SSG in dev the same way the node middleware does\n type: route.type === \"ssg\" ? \"ssr\" : route.type,\n layouts: layouts === null || layouts === void 0 ? void 0 : layouts.map(function(layout) {\n return {\n contextKey: layout.contextKey\n };\n }),\n middlewares: middlewares === null || middlewares === void 0 ? void 0 : middlewares.map(function(middleware) {\n return {\n contextKey: middleware.contextKey\n };\n })\n };\n}\nfunction stubRouteBuildInfo(route, preloads) {\n var _ref;\n var _route_middlewares;\n var pageType = route.type === \"ssg\" ? \"ssr\" : route.type;\n return {\n type: pageType,\n path: route.page,\n routeFile: route.file,\n middlewares: (_ref = (_route_middlewares = route.middlewares) === null || _route_middlewares === void 0 ? void 0 : _route_middlewares.map(function(middleware) {\n return middleware.contextKey;\n })) !== null && _ref !== void 0 ? _ref : [],\n preloadPath: \"\",\n cssPreloadPath: \"\",\n loaderPath: \"\",\n cleanPath: route.urlCleanPath || route.page,\n htmlPath: \"\",\n clientJsPath: \"\",\n serverJsPath: \"\",\n params: {},\n preloads,\n css: [],\n layoutCSS: []\n };\n}\nfunction generateWorkerdDevEntryModule(args) {\n var _options_router;\n var { root, options, routerRoot, routePaths, preloads } = args;\n var manifest = getManifest({\n routerRoot: resolve(root, routerRoot),\n ignoredRouteFiles: (_options_router = options.router) === null || _options_router === void 0 ? void 0 : _options_router.ignoredRouteFiles,\n routePaths\n });\n if (!manifest) {\n throw new Error(\"[one] workerd dev: no routes manifest\");\n }\n var apiImports = /* @__PURE__ */ new Map();\n var middlewareImports = /* @__PURE__ */ new Map();\n var routeToBuildInfo = {};\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = manifest.pageRoutes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var route = _step.value;\n var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;\n try {\n for (var _iterator1 = (route.middlewares || [])[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {\n var middleware = _step1.value;\n if (!middleware.contextKey || middlewareImports.has(middleware.contextKey)) continue;\n middlewareImports.set(middleware.contextKey, toImportHref(root, routerRoot, middleware.contextKey));\n }\n } catch (err) {\n _didIteratorError1 = true;\n _iteratorError1 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion1 && _iterator1.return != null) {\n _iterator1.return();\n }\n } finally {\n if (_didIteratorError1) {\n throw _iteratorError1;\n }\n }\n }\n if (route.file) {\n routeToBuildInfo[route.file] = stubRouteBuildInfo(route, preloads);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = void 0;\n try {\n for (var _iterator2 = manifest.apiRoutes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var route1 = _step2.value;\n if (route1.file) {\n apiImports.set(route1.page, toImportHref(root, routerRoot, route1.file));\n }\n var _iteratorNormalCompletion3 = true, _didIteratorError3 = false, _iteratorError3 = void 0;\n try {\n for (var _iterator3 = (route1.middlewares || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var middleware1 = _step3.value;\n if (!middleware1.contextKey || middlewareImports.has(middleware1.contextKey)) continue;\n middlewareImports.set(middleware1.contextKey, toImportHref(root, routerRoot, middleware1.contextKey));\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return != null) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n var pageRoutes = manifest.pageRoutes.map(stripRouteForWorker);\n var apiRoutes = manifest.apiRoutes.map(stripRouteForWorker);\n var buildInfo = {\n constants: {\n CACHE_KEY\n },\n oneOptions: options,\n routeToBuildInfo,\n pathToRoute: {},\n routeMap: {},\n manifest: {\n pageRoutes,\n apiRoutes,\n allRoutes: [\n ...pageRoutes,\n ...apiRoutes\n ]\n },\n preloads: Object.fromEntries(preloads.map(function(preload) {\n return [\n preload,\n true\n ];\n })),\n cssPreloads: {},\n loaders: {}\n };\n var spaPreloadScripts = preloads.map(function(preload) {\n return `<script type=\"module\" src=\"${preload}\"></script>`;\n }).join(\"\");\n return `if (typeof MessageChannel === 'undefined') {\n globalThis.MessageChannel = class MessageChannel {\n constructor() {\n this.port1 = { postMessage: () => {}, onmessage: null, close: () => {} }\n this.port2 = { postMessage: () => {}, onmessage: null, close: () => {} }\n }\n }\n}\n\nimport { serve, setFetchStaticHtml } from 'one/serve-worker'\n\nconst lazyRoutes = {\n serverEntry: () => import(${JSON.stringify(virtualEntryId)}),\n api: {\n${serializeImportMap([\n ...apiImports\n ])}\n },\n middlewares: {\n${serializeImportMap([\n ...middlewareImports\n ])}\n }\n}\n\nconst buildInfo = ${JSON.stringify(buildInfo)}\n\nlet server\n\nexport default {\n async fetch(request, env, ctx) {\n const url = new URL(request.url)\n const pathname = url.pathname\n\n if (pathname === '/status' || pathname.startsWith('/status?')) {\n return new Response('packager-status:running', {\n headers: { 'content-type': 'text/plain' },\n })\n }\n\n if (!server) {\n server = await serve(buildInfo, lazyRoutes, { disableModuleCache: true })\n }\n\n if (env && env.ASSETS) {\n setFetchStaticHtml(async (path) => {\n try {\n const assetUrl = new URL(request.url)\n assetUrl.pathname = path\n const assetResponse = await env.ASSETS.fetch(new Request(assetUrl))\n if (assetResponse && assetResponse.ok) {\n return await assetResponse.text()\n }\n } catch {}\n return null\n })\n }\n\n try {\n const response = await server.fetch(request, env, ctx)\n\n if (!response || response.status === 404) {\n if (env && env.ASSETS) {\n try {\n const assetResponse = await env.ASSETS.fetch(request)\n if (assetResponse && assetResponse.status !== 404) {\n return assetResponse\n }\n } catch {}\n }\n }\n\n if (!response) {\n if (request.method === 'GET' || request.method === 'HEAD') {\n return new Response(\n '<!DOCTYPE html><html><head>' +\n ${JSON.stringify(spaPreloadScripts)} +\n '</head></html>',\n { headers: { 'content-type': 'text/html' } }\n )\n }\n return new Response('Not Found', { status: 404 })\n }\n\n return response\n } finally {\n setFetchStaticHtml(null)\n }\n }\n}\n`;\n}\nfunction createWorkerdDevPlugins(options, root, routeIndex) {\n var _options_web, _options_web1;\n if (!shouldEnableWorkerdDev((_options_web = options.web) === null || _options_web === void 0 ? void 0 : _options_web.deploy, root)) {\n return [];\n }\n var cacheDir = join(root, WORKERD_DEV_DIR);\n var wranglerInputPath = join(cacheDir, \"_wrangler.input.jsonc\");\n var workerEntryPath = join(cacheDir, \"worker-entry.js\");\n mkdirSync(cacheDir, {\n recursive: true\n });\n writeFileSync(workerEntryPath, `export { default } from ${JSON.stringify(workerdDevEntryId)}\n`);\n var userWranglerConfig = loadUserWranglerConfigSync(root);\n var projectName = getCloudflareProjectNameSync(root);\n var wranglerInputConfig = createCloudflareWranglerConfig(projectName, userWranglerConfig === null || userWranglerConfig === void 0 ? void 0 : userWranglerConfig.config);\n wranglerInputConfig.main = \"worker-entry.js\";\n writeFileSync(wranglerInputPath, `${JSON.stringify(wranglerInputConfig, null, 2)}\n`);\n var preloads = ((_options_web1 = options.web) === null || _options_web1 === void 0 ? void 0 : _options_web1.experimentalBundledDev) ? [\n \"/bundledDevClient.mjs\",\n \"/assets/_virtual_one-entry.js\"\n ] : [\n \"/@vite/client\",\n virtalEntryIdClient\n ];\n var empty = resolvePath(\"@vxrn/utils/empty\", root);\n var absorbed = absorbedPackageAliases(root, \"web\");\n var preparePlugin = {\n name: \"one:workerd-dev-prepare\",\n apply: \"serve\",\n enforce: \"pre\",\n config() {\n return {\n environments: {\n worker: {\n define: {\n ...getPlatformEnvDefine(\"ssr\"),\n \"process.env.TAMAGUI_IS_SERVER\": JSON.stringify(\"1\"),\n \"process.env.TAMAGUI_KEEP_THEMES\": JSON.stringify(\"1\"),\n \"process.env.ONE_CACHE_KEY\": JSON.stringify(CACHE_KEY)\n },\n optimizeDeps: {\n include: [\n \"react\",\n \"react-dom\",\n \"react-dom/client\",\n \"react-dom/server.browser\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\"\n ]\n },\n build: {\n rolldownOptions: {\n shimMissingExports: true\n }\n }\n }\n }\n };\n },\n // environment resolve options have no alias field; match the production\n // worker aliases with a worker-only resolveId (rolldown cannot parse RN Flow)\n resolveId: {\n filter: {\n id: /^(react-native(\\/|$|-safe-area-context$)|@react-native\\/assets-registry\\/registry$)/\n },\n handler(source) {\n if (this.environment.name !== \"worker\") return;\n if (/^react-native\\/Libraries\\//.test(source)) return empty;\n if (source === \"react-native/asset-registry\" || source === \"@react-native/assets-registry/registry\") return resolvePath(\"react-native-web/dist/modules/AssetRegistry\", root);\n if (source === \"react-native/package.json\") return resolvePath(\"react-native-web/package.json\", root);\n if (source === \"react-native\") return resolvePath(\"react-native-web\", root);\n if (source in absorbed) return absorbed[source];\n }\n },\n configureServer(server) {\n if (!server.environments.worker) {\n throw new Error(`[one] ONE_EXPERIMENTAL_WORKER_DEV=1 is set but @cloudflare/vite-plugin did not register a \"worker\" environment. Expected wrangler config at ${wranglerInputPath}.`);\n }\n console.info(\"[one] experimental workerd dev enabled (ONE_EXPERIMENTAL_WORKER_DEV=1)\");\n }\n };\n var virtualPlugin = {\n name: \"one:workerd-dev-entry\",\n apply: \"serve\",\n resolveId: {\n filter: {\n id: exactRegex(workerdDevEntryId)\n },\n handler(id) {\n if (this.environment.name !== \"worker\") return;\n if (id === workerdDevEntryId) return resolvedWorkerdDevEntryId;\n }\n },\n load: {\n filter: {\n id: exactRegex(resolvedWorkerdDevEntryId)\n },\n handler() {\n if (this.environment.name !== \"worker\") return;\n return generateWorkerdDevEntryModule({\n root,\n options,\n routerRoot: getRouterRootFromOneOptions(options),\n routePaths: routeIndex.getPaths(),\n preloads\n });\n }\n },\n hotUpdate(param) {\n var { file } = param;\n if (this.environment.name !== \"worker\") return;\n var graph = this.environment.moduleGraph;\n var entry = graph.getModuleById(resolvedWorkerdDevEntryId);\n if (!entry) return;\n var modules = graph.getModulesByFile(file);\n if (!(modules === null || modules === void 0 ? void 0 : modules.size)) return;\n graph.invalidateModule(entry);\n }\n };\n var cloudflarePlugins = cloudflare({\n configPath: wranglerInputPath,\n viteEnvironment: {\n name: \"worker\"\n }\n }).map(serveOnly);\n return [\n preparePlugin,\n virtualPlugin,\n ...cloudflarePlugins\n ];\n}\nexport {\n createWorkerdDevPlugins,\n generateWorkerdDevEntryModule,\n shouldEnableWorkerdDev,\n workerdDevEntryId\n};\n//# sourceMappingURL=workerdDevPlugin.js.map\n"],"mappings":";;;;;;;;;;;;;;;AAaA,IAAI,oBAAoB;AACxB,IAAI,4BAA4B,KAAK;AACrC,IAAI,kBAAkB;AACtB,SAAS,UAAU,QAAQ;CACzB,IAAI,WAAW,OAAO;CACtB,OAAO;EACL,GAAG;EACH,MAAM,QAAQ,KAAK;GACjB,IAAI,IAAI,YAAY,SAAS,OAAO;GACpC,IAAI,OAAO,aAAa,YAAY,OAAO,SAAS,QAAQ,GAAG;GAC/D,IAAI,aAAa,SAAS,OAAO;GACjC,OAAO;EACT;CACF;AACF;AACA,SAAS,aAAa,MAAM,YAAY,WAAW;CACjD,IAAI,MAAM,UAAU,QAAQ,SAAS,EAAE;CACvC,OAAO,cAAc,QAAQ,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC;AACvD;AACA,SAAS,mBAAmB,SAAS;CACnC,OAAO,QAAQ,IAAI,SAAS,OAAO;EACjC,IAAI,CAAC,KAAK,QAAQ;EAClB,OAAO,KAAK,KAAK,UAAU,GAAG,EAAE,iBAAiB,KAAK,UAAU,IAAI,EAAE;CACxE,CAAC,CAAC,CAAC,KAAK,KAAK;AACf;AACA,SAAS,oBAAoB,OAAO;CAClC,IAAI,EAAE,SAAS,aAAa,GAAG,SAAS;CACxC,OAAO;EACL,GAAG;EAEH,MAAM,MAAM,SAAS,QAAQ,QAAQ,MAAM;EAC3C,SAAS,YAAY,QAAQ,YAAY,KAAK,IAAI,KAAK,IAAI,QAAQ,IAAI,SAAS,QAAQ;GACtF,OAAO,EACL,YAAY,OAAO,WACrB;EACF,CAAC;EACD,aAAa,gBAAgB,QAAQ,gBAAgB,KAAK,IAAI,KAAK,IAAI,YAAY,IAAI,SAAS,YAAY;GAC1G,OAAO,EACL,YAAY,WAAW,WACzB;EACF,CAAC;CACH;AACF;AACA,SAAS,mBAAmB,OAAO,UAAU;CAC3C,IAAI;CACJ,IAAI;CACJ,IAAI,WAAW,MAAM,SAAS,QAAQ,QAAQ,MAAM;CACpD,OAAO;EACL,MAAM;EACN,MAAM,MAAM;EACZ,WAAW,MAAM;EACjB,cAAc,QAAQ,qBAAqB,MAAM,iBAAiB,QAAQ,uBAAuB,KAAK,IAAI,KAAK,IAAI,mBAAmB,IAAI,SAAS,YAAY;GAC7J,OAAO,WAAW;EACpB,CAAC,OAAO,QAAQ,SAAS,KAAK,IAAI,OAAO,CAAC;EAC1C,aAAa;EACb,gBAAgB;EAChB,YAAY;EACZ,WAAW,MAAM,gBAAgB,MAAM;EACvC,UAAU;EACV,cAAc;EACd,cAAc;EACd,QAAQ,CAAC;EACT;EACA,KAAK,CAAC;EACN,WAAW,CAAC;CACd;AACF;AACA,SAAS,8BAA8B,MAAM;CAC3C,IAAI;CACJ,IAAI,EAAE,MAAM,SAAS,YAAY,YAAY,aAAa;CAC1D,IAAI,WAAW,YAAY;EACzB,YAAY,QAAQ,MAAM,UAAU;EACpC,oBAAoB,kBAAkB,QAAQ,YAAY,QAAQ,oBAAoB,KAAK,IAAI,KAAK,IAAI,gBAAgB;EACxH;CACF,CAAC;CACD,IAAI,CAAC,UAAU;EACb,MAAM,IAAI,MAAM,uCAAuC;CACzD;CACA,IAAI,6BAA6B,IAAI,IAAI;CACzC,IAAI,oCAAoC,IAAI,IAAI;CAChD,IAAI,mBAAmB,CAAC;CACxB,IAAI,4BAA4B,MAAM,oBAAoB,OAAO,iBAAiB,KAAK;CACvF,IAAI;EACF,KAAK,IAAI,YAAY,SAAS,WAAW,OAAO,SAAS,CAAC,GAAG,OAAO,EAAE,6BAA6B,QAAQ,UAAU,KAAK,EAAC,CAAE,OAAO,4BAA4B,MAAM;GACpK,IAAI,QAAQ,MAAM;GAClB,IAAI,6BAA6B,MAAM,qBAAqB,OAAO,kBAAkB,KAAK;GAC1F,IAAI;IACF,KAAK,IAAI,cAAc,MAAM,eAAe,CAAC,EAAC,CAAE,OAAO,SAAS,CAAC,GAAG,QAAQ,EAAE,8BAA8B,SAAS,WAAW,KAAK,EAAC,CAAE,OAAO,6BAA6B,MAAM;KAChL,IAAI,aAAa,OAAO;KACxB,IAAI,CAAC,WAAW,cAAc,kBAAkB,IAAI,WAAW,UAAU,GAAG;KAC5E,kBAAkB,IAAI,WAAW,YAAY,aAAa,MAAM,YAAY,WAAW,UAAU,CAAC;IACpG;GACF,SAAS,KAAK;IACZ,qBAAqB;IACrB,kBAAkB;GACpB,UAAU;IACR,IAAI;KACF,IAAI,CAAC,8BAA8B,WAAW,UAAU,MAAM;MAC5D,WAAW,OAAO;KACpB;IACF,UAAU;KACR,IAAI,oBAAoB;MACtB,MAAM;KACR;IACF;GACF;GACA,IAAI,MAAM,MAAM;IACd,iBAAiB,MAAM,QAAQ,mBAAmB,OAAO,QAAQ;GACnE;EACF;CACF,SAAS,KAAK;EACZ,oBAAoB;EACpB,iBAAiB;CACnB,UAAU;EACR,IAAI;GACF,IAAI,CAAC,6BAA6B,UAAU,UAAU,MAAM;IAC1D,UAAU,OAAO;GACnB;EACF,UAAU;GACR,IAAI,mBAAmB;IACrB,MAAM;GACR;EACF;CACF;CACA,IAAI,6BAA6B,MAAM,qBAAqB,OAAO,kBAAkB,KAAK;CAC1F,IAAI;EACF,KAAK,IAAI,aAAa,SAAS,UAAU,OAAO,SAAS,CAAC,GAAG,QAAQ,EAAE,8BAA8B,SAAS,WAAW,KAAK,EAAC,CAAE,OAAO,6BAA6B,MAAM;GACzK,IAAI,SAAS,OAAO;GACpB,IAAI,OAAO,MAAM;IACf,WAAW,IAAI,OAAO,MAAM,aAAa,MAAM,YAAY,OAAO,IAAI,CAAC;GACzE;GACA,IAAI,6BAA6B,MAAM,qBAAqB,OAAO,kBAAkB,KAAK;GAC1F,IAAI;IACF,KAAK,IAAI,cAAc,OAAO,eAAe,CAAC,EAAC,CAAE,OAAO,SAAS,CAAC,GAAG,QAAQ,EAAE,8BAA8B,SAAS,WAAW,KAAK,EAAC,CAAE,OAAO,6BAA6B,MAAM;KACjL,IAAI,cAAc,OAAO;KACzB,IAAI,CAAC,YAAY,cAAc,kBAAkB,IAAI,YAAY,UAAU,GAAG;KAC9E,kBAAkB,IAAI,YAAY,YAAY,aAAa,MAAM,YAAY,YAAY,UAAU,CAAC;IACtG;GACF,SAAS,KAAK;IACZ,qBAAqB;IACrB,kBAAkB;GACpB,UAAU;IACR,IAAI;KACF,IAAI,CAAC,8BAA8B,WAAW,UAAU,MAAM;MAC5D,WAAW,OAAO;KACpB;IACF,UAAU;KACR,IAAI,oBAAoB;MACtB,MAAM;KACR;IACF;GACF;EACF;CACF,SAAS,KAAK;EACZ,qBAAqB;EACrB,kBAAkB;CACpB,UAAU;EACR,IAAI;GACF,IAAI,CAAC,8BAA8B,WAAW,UAAU,MAAM;IAC5D,WAAW,OAAO;GACpB;EACF,UAAU;GACR,IAAI,oBAAoB;IACtB,MAAM;GACR;EACF;CACF;CACA,IAAI,aAAa,SAAS,WAAW,IAAI,mBAAmB;CAC5D,IAAI,YAAY,SAAS,UAAU,IAAI,mBAAmB;CAC1D,IAAI,YAAY;EACd,WAAW,EACT,UACF;EACA,YAAY;EACZ;EACA,aAAa,CAAC;EACd,UAAU,CAAC;EACX,UAAU;GACR;GACA;GACA,WAAW,CACT,GAAG,YACH,GAAG,SACL;EACF;EACA,UAAU,OAAO,YAAY,SAAS,IAAI,SAAS,SAAS;GAC1D,OAAO,CACL,SACA,IACF;EACF,CAAC,CAAC;EACF,aAAa,CAAC;EACd,SAAS,CAAC;CACZ;CACA,IAAI,oBAAoB,SAAS,IAAI,SAAS,SAAS;EACrD,OAAO,8BAA8B,QAAQ;CAC/C,CAAC,CAAC,CAAC,KAAK,EAAE;CACV,OAAO;;;;;;;;;;;;8BAYqB,KAAK,UAAU,cAAc,EAAE;;EAE3D,mBAAmB,CACjB,GAAG,UACL,CAAC,EAAE;;;EAGH,mBAAmB,CACjB,GAAG,iBACL,CAAC,EAAE;;;;oBAIe,KAAK,UAAU,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAmD9B,KAAK,UAAU,iBAAiB,EAAE;;;;;;;;;;;;;;;AAelD;AACA,SAAS,wBAAwB,SAAS,MAAM,YAAY;CAC1D,IAAI,cAAc;CAClB,IAAI,CAAC,wBAAwB,eAAe,QAAQ,SAAS,QAAQ,iBAAiB,KAAK,IAAI,KAAK,IAAI,aAAa,QAAQ,IAAI,GAAG;EAClI,OAAO,CAAC;CACV;CACA,IAAI,WAAW,KAAK,MAAM,eAAe;CACzC,IAAI,oBAAoB,KAAK,UAAU,uBAAuB;CAC9D,IAAI,kBAAkB,KAAK,UAAU,iBAAiB;CACtD,UAAU,UAAU,EAClB,WAAW,KACb,CAAC;CACD,cAAc,iBAAiB,2BAA2B,KAAK,UAAU,iBAAiB,EAAE;CAC7F;CACC,IAAI,qBAAqB,2BAA2B,IAAI;CACxD,IAAI,cAAc,6BAA6B,IAAI;CACnD,IAAI,sBAAsB,+BAA+B,aAAa,uBAAuB,QAAQ,uBAAuB,KAAK,IAAI,KAAK,IAAI,mBAAmB,MAAM;CACvK,oBAAoB,OAAO;CAC3B,cAAc,mBAAmB,GAAG,KAAK,UAAU,qBAAqB,MAAM,CAAC,EAAE;CAClF;CACC,IAAI,aAAa,gBAAgB,QAAQ,SAAS,QAAQ,kBAAkB,KAAK,IAAI,KAAK,IAAI,cAAc,0BAA0B,CACpI,yBACA,+BACF,IAAI,CACF,iBACA,mBACF;CACA,IAAI,QAAQ,YAAY,qBAAqB,IAAI;CACjD,IAAI,WAAW,uBAAuB,MAAM,KAAK;CACjD,IAAI,gBAAgB;EAClB,MAAM;EACN,OAAO;EACP,SAAS;EACT,SAAS;GACP,OAAO,EACL,cAAc,EACZ,QAAQ;IACN,QAAQ;KACN,GAAG,qBAAqB,KAAK;KAC7B,iCAAiC,KAAK,UAAU,GAAG;KACnD,mCAAmC,KAAK,UAAU,GAAG;KACrD,6BAA6B,KAAK,UAAU,SAAS;IACvD;IACA,cAAc,EACZ,SAAS;KACP;KACA;KACA;KACA;KACA;KACA;IACF,EACF;IACA,OAAO,EACL,iBAAiB,EACf,oBAAoB,KACtB,EACF;GACF,EACF,EACF;EACF;EAGA,WAAW;GACT,QAAQ,EACN,IAAI,sFACN;GACA,QAAQ,QAAQ;IACd,IAAI,KAAK,YAAY,SAAS,UAAU;IACxC,IAAI,6BAA6B,KAAK,MAAM,GAAG,OAAO;IACtD,IAAI,WAAW,iCAAiC,WAAW,0CAA0C,OAAO,YAAY,+CAA+C,IAAI;IAC3K,IAAI,WAAW,6BAA6B,OAAO,YAAY,iCAAiC,IAAI;IACpG,IAAI,WAAW,gBAAgB,OAAO,YAAY,oBAAoB,IAAI;IAC1E,IAAI,UAAU,UAAU,OAAO,SAAS;GAC1C;EACF;EACA,gBAAgB,QAAQ;GACtB,IAAI,CAAC,OAAO,aAAa,QAAQ;IAC/B,MAAM,IAAI,MAAM,+IAA+I,kBAAkB,EAAE;GACrL;GACA,QAAQ,KAAK,wEAAwE;EACvF;CACF;CACA,IAAI,gBAAgB;EAClB,MAAM;EACN,OAAO;EACP,WAAW;GACT,QAAQ,EACN,IAAI,WAAW,iBAAiB,EAClC;GACA,QAAQ,IAAI;IACV,IAAI,KAAK,YAAY,SAAS,UAAU;IACxC,IAAI,wCAA0B,OAAO;GACvC;EACF;EACA,MAAM;GACJ,QAAQ,EACN,IAAI,WAAW,yBAAyB,EAC1C;GACA,UAAU;IACR,IAAI,KAAK,YAAY,SAAS,UAAU;IACxC,OAAO,8BAA8B;KACnC;KACA;KACA,YAAY,4BAA4B,OAAO;KAC/C,YAAY,WAAW,SAAS;KAChC;IACF,CAAC;GACH;EACF;EACA,UAAU,OAAO;GACf,IAAI,EAAE,SAAS;GACf,IAAI,KAAK,YAAY,SAAS,UAAU;GACxC,IAAI,QAAQ,KAAK,YAAY;GAC7B,IAAI,QAAQ,MAAM,cAAc,yBAAyB;GACzD,IAAI,CAAC,OAAO;GACZ,IAAI,UAAU,MAAM,iBAAiB,IAAI;GACzC,IAAI,EAAE,YAAY,QAAQ,YAAY,KAAK,IAAI,KAAK,IAAI,QAAQ,OAAO;GACvE,MAAM,iBAAiB,KAAK;EAC9B;CACF;CACA,IAAI,oBAAoB,WAAW;EACjC,YAAY;EACZ,iBAAiB,EACf,MAAM,SACR;CACF,CAAC,CAAC,CAAC,IAAI,SAAS;CAChB,OAAO;EACL;EACA;EACA,GAAG;CACL;AACF"}
|
|
1
|
+
{"version":3,"file":"workerdDevPlugin.native.js","names":[],"sources":["esm/vite/plugins/workerdDevPlugin.native.js"],"sourcesContent":["import { mkdirSync, writeFileSync } from \"fs\";\nimport { join, resolve } from \"path\";\nimport { pathToFileURL } from \"url\";\nimport { resolvePath } from \"@vxrn/resolve\";\nimport { cloudflare } from \"@cloudflare/vite-plugin\";\nimport { getPlatformEnvDefine } from \"@vxrn/utils\";\nimport { exactRegex } from \"rolldown/filter\";\nimport { CACHE_KEY } from \"../../constants\";\nimport { virtalEntryIdClient, virtualEntryId } from \"./virtualEntryConstants\";\nimport { getManifest } from \"../getManifest\";\nimport { getRouterRootFromOneOptions } from \"../../utils/getRouterRootFromOneOptions\";\nimport { absorbedPackageAliases } from \"../../utils/absorbedPackages\";\nimport { createCloudflareWranglerConfig, getCloudflareProjectNameSync, loadUserWranglerConfigSync, shouldEnableWorkerdDev } from \"../cloudflareWranglerConfig\";\nvar workerdDevEntryId = \"virtual:one-workerd-dev-entry\";\nvar resolvedWorkerdDevEntryId = `\\0${workerdDevEntryId}`;\nvar WORKERD_DEV_DIR = \"node_modules/.one-workerd-dev\";\nfunction serveOnly(plugin) {\n var existing = plugin.apply;\n return {\n ...plugin,\n apply(config, env) {\n if (env.command !== \"serve\") return false;\n if (typeof existing === \"function\") return existing(config, env);\n if (existing === \"build\") return false;\n return true;\n }\n };\n}\nfunction toImportHref(root, routerRoot, routeFile) {\n var rel = routeFile.replace(/^\\.\\//, \"\");\n return pathToFileURL(resolve(root, routerRoot, rel)).href;\n}\nfunction serializeImportMap(entries) {\n return entries.map(function(param) {\n var [key, href] = param;\n return ` ${JSON.stringify(key)}: () => import(${JSON.stringify(href)})`;\n }).join(\",\\n\");\n}\nfunction stripRouteForWorker(route) {\n var { layouts, middlewares, ...rest } = route;\n return {\n ...rest,\n // live-render SSG in dev the same way the node middleware does\n type: route.type === \"ssg\" ? \"ssr\" : route.type,\n layouts: layouts === null || layouts === void 0 ? void 0 : layouts.map(function(layout) {\n return {\n contextKey: layout.contextKey\n };\n }),\n middlewares: middlewares === null || middlewares === void 0 ? void 0 : middlewares.map(function(middleware) {\n return {\n contextKey: middleware.contextKey\n };\n })\n };\n}\nfunction stubRouteBuildInfo(route, preloads) {\n var _ref;\n var _route_middlewares;\n var pageType = route.type === \"ssg\" ? \"ssr\" : route.type;\n return {\n type: pageType,\n path: route.page,\n routeFile: route.file,\n middlewares: (_ref = (_route_middlewares = route.middlewares) === null || _route_middlewares === void 0 ? void 0 : _route_middlewares.map(function(middleware) {\n return middleware.contextKey;\n })) !== null && _ref !== void 0 ? _ref : [],\n preloadPath: \"\",\n cssPreloadPath: \"\",\n loaderPath: \"\",\n cleanPath: route.urlCleanPath || route.page,\n htmlPath: \"\",\n clientJsPath: \"\",\n serverJsPath: \"\",\n params: {},\n preloads,\n css: [],\n layoutCSS: []\n };\n}\nfunction generateWorkerdDevEntryModule(args) {\n var _options_router;\n var { root, options, routerRoot, routePaths, preloads } = args;\n var manifest = getManifest({\n routerRoot: resolve(root, routerRoot),\n ignoredRouteFiles: (_options_router = options.router) === null || _options_router === void 0 ? void 0 : _options_router.ignoredRouteFiles,\n routePaths\n });\n if (!manifest) {\n throw new Error(\"[one] workerd dev: no routes manifest\");\n }\n var apiImports = /* @__PURE__ */ new Map();\n var middlewareImports = /* @__PURE__ */ new Map();\n var routeToBuildInfo = {};\n var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;\n try {\n for (var _iterator = manifest.pageRoutes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var route = _step.value;\n var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;\n try {\n for (var _iterator1 = (route.middlewares || [])[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {\n var middleware = _step1.value;\n if (!middleware.contextKey || middlewareImports.has(middleware.contextKey)) continue;\n middlewareImports.set(middleware.contextKey, toImportHref(root, routerRoot, middleware.contextKey));\n }\n } catch (err) {\n _didIteratorError1 = true;\n _iteratorError1 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion1 && _iterator1.return != null) {\n _iterator1.return();\n }\n } finally {\n if (_didIteratorError1) {\n throw _iteratorError1;\n }\n }\n }\n if (route.file) {\n routeToBuildInfo[route.file] = stubRouteBuildInfo(route, preloads);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = void 0;\n try {\n for (var _iterator2 = manifest.apiRoutes[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var route1 = _step2.value;\n if (route1.file) {\n apiImports.set(route1.page, toImportHref(root, routerRoot, route1.file));\n }\n var _iteratorNormalCompletion3 = true, _didIteratorError3 = false, _iteratorError3 = void 0;\n try {\n for (var _iterator3 = (route1.middlewares || [])[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var middleware1 = _step3.value;\n if (!middleware1.contextKey || middlewareImports.has(middleware1.contextKey)) continue;\n middlewareImports.set(middleware1.contextKey, toImportHref(root, routerRoot, middleware1.contextKey));\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return != null) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n var pageRoutes = manifest.pageRoutes.map(stripRouteForWorker);\n var apiRoutes = manifest.apiRoutes.map(stripRouteForWorker);\n var buildInfo = {\n constants: {\n CACHE_KEY\n },\n oneOptions: options,\n routeToBuildInfo,\n pathToRoute: {},\n routeMap: {},\n manifest: {\n pageRoutes,\n apiRoutes,\n allRoutes: [\n ...pageRoutes,\n ...apiRoutes\n ]\n },\n preloads: Object.fromEntries(preloads.map(function(preload) {\n return [\n preload,\n true\n ];\n })),\n cssPreloads: {},\n loaders: {}\n };\n var spaPreloadScripts = preloads.map(function(preload) {\n return `<script type=\"module\" src=\"${preload}\"></script>`;\n }).join(\"\");\n return `if (typeof MessageChannel === 'undefined') {\n globalThis.MessageChannel = class MessageChannel {\n constructor() {\n this.port1 = { postMessage: () => {}, onmessage: null, close: () => {} }\n this.port2 = { postMessage: () => {}, onmessage: null, close: () => {} }\n }\n }\n}\n\nimport { serve } from 'one/serve-worker'\n\nconst lazyRoutes = {\n serverEntry: () => import(${JSON.stringify(virtualEntryId)}),\n api: {\n${serializeImportMap([\n ...apiImports\n ])}\n },\n middlewares: {\n${serializeImportMap([\n ...middlewareImports\n ])}\n }\n}\n\nconst buildInfo = ${JSON.stringify(buildInfo)}\n\nlet server\n\nexport default {\n async fetch(request, env, ctx) {\n const url = new URL(request.url)\n const pathname = url.pathname\n\n if (pathname === '/status' || pathname.startsWith('/status?')) {\n return new Response('packager-status:running', {\n headers: { 'content-type': 'text/plain' },\n })\n }\n\n if (!server) {\n server = await serve(buildInfo, lazyRoutes, { disableModuleCache: true })\n }\n\n const fetchStaticHtml = env && env.ASSETS\n ? async (path) => {\n try {\n const assetUrl = new URL(request.url)\n assetUrl.pathname = path\n const assetResponse = await env.ASSETS.fetch(new Request(assetUrl))\n if (assetResponse && assetResponse.ok) {\n return await assetResponse.text()\n }\n } catch {}\n return null\n }\n : undefined\n\n const response = await server.fetch(request, env, ctx, fetchStaticHtml)\n\n if (!response || response.status === 404) {\n if (env && env.ASSETS) {\n try {\n const assetResponse = await env.ASSETS.fetch(request)\n if (assetResponse && assetResponse.status !== 404) {\n return assetResponse\n }\n } catch {}\n }\n }\n\n if (!response) {\n if (request.method === 'GET' || request.method === 'HEAD') {\n return new Response(\n '<!DOCTYPE html><html><head>' +\n ${JSON.stringify(spaPreloadScripts)} +\n '</head></html>',\n { headers: { 'content-type': 'text/html' } }\n )\n }\n return new Response('Not Found', { status: 404 })\n }\n\n return response\n }\n}\n`;\n}\nfunction createWorkerdDevPlugins(options, root, routeIndex) {\n var _options_web, _options_web1;\n if (!shouldEnableWorkerdDev((_options_web = options.web) === null || _options_web === void 0 ? void 0 : _options_web.deploy, root)) {\n return [];\n }\n var cacheDir = join(root, WORKERD_DEV_DIR);\n var wranglerInputPath = join(cacheDir, \"_wrangler.input.jsonc\");\n var workerEntryPath = join(cacheDir, \"worker-entry.js\");\n mkdirSync(cacheDir, {\n recursive: true\n });\n writeFileSync(workerEntryPath, `export { default } from ${JSON.stringify(workerdDevEntryId)}\n`);\n var userWranglerConfig = loadUserWranglerConfigSync(root);\n var projectName = getCloudflareProjectNameSync(root);\n var wranglerInputConfig = createCloudflareWranglerConfig(projectName, userWranglerConfig === null || userWranglerConfig === void 0 ? void 0 : userWranglerConfig.config);\n wranglerInputConfig.main = \"worker-entry.js\";\n writeFileSync(wranglerInputPath, `${JSON.stringify(wranglerInputConfig, null, 2)}\n`);\n var preloads = ((_options_web1 = options.web) === null || _options_web1 === void 0 ? void 0 : _options_web1.experimentalBundledDev) ? [\n \"/bundledDevClient.mjs\",\n \"/assets/_virtual_one-entry.js\"\n ] : [\n \"/@vite/client\",\n virtalEntryIdClient\n ];\n var empty = resolvePath(\"@vxrn/utils/empty\", root);\n var absorbed = absorbedPackageAliases(root, \"web\");\n var preparePlugin = {\n name: \"one:workerd-dev-prepare\",\n apply: \"serve\",\n enforce: \"pre\",\n config() {\n return {\n environments: {\n worker: {\n define: {\n ...getPlatformEnvDefine(\"ssr\"),\n \"process.env.TAMAGUI_IS_SERVER\": JSON.stringify(\"1\"),\n \"process.env.TAMAGUI_KEEP_THEMES\": JSON.stringify(\"1\"),\n \"process.env.ONE_CACHE_KEY\": JSON.stringify(CACHE_KEY)\n },\n optimizeDeps: {\n include: [\n \"react\",\n \"react-dom\",\n \"react-dom/client\",\n \"react-dom/server.browser\",\n \"react/jsx-runtime\",\n \"react/jsx-dev-runtime\"\n ]\n },\n build: {\n rolldownOptions: {\n shimMissingExports: true\n }\n }\n }\n }\n };\n },\n // environment resolve options have no alias field; match the production\n // worker aliases with a worker-only resolveId (rolldown cannot parse RN Flow)\n resolveId: {\n filter: {\n id: /^(react-native(\\/|$|-safe-area-context$)|@react-native\\/assets-registry\\/registry$)/\n },\n handler(source) {\n if (this.environment.name !== \"worker\") return;\n if (/^react-native\\/Libraries\\//.test(source)) return empty;\n if (source === \"react-native/asset-registry\" || source === \"@react-native/assets-registry/registry\") return resolvePath(\"react-native-web/dist/modules/AssetRegistry\", root);\n if (source === \"react-native/package.json\") return resolvePath(\"react-native-web/package.json\", root);\n if (source === \"react-native\") return resolvePath(\"react-native-web\", root);\n if (source in absorbed) return absorbed[source];\n }\n },\n configureServer(server) {\n if (!server.environments.worker) {\n throw new Error(`[one] ONE_EXPERIMENTAL_WORKER_DEV=1 is set but @cloudflare/vite-plugin did not register a \"worker\" environment. Expected wrangler config at ${wranglerInputPath}.`);\n }\n console.info(\"[one] experimental workerd dev enabled (ONE_EXPERIMENTAL_WORKER_DEV=1)\");\n }\n };\n var virtualPlugin = {\n name: \"one:workerd-dev-entry\",\n apply: \"serve\",\n resolveId: {\n filter: {\n id: exactRegex(workerdDevEntryId)\n },\n handler(id) {\n if (this.environment.name !== \"worker\") return;\n if (id === workerdDevEntryId) return resolvedWorkerdDevEntryId;\n }\n },\n load: {\n filter: {\n id: exactRegex(resolvedWorkerdDevEntryId)\n },\n handler() {\n if (this.environment.name !== \"worker\") return;\n return generateWorkerdDevEntryModule({\n root,\n options,\n routerRoot: getRouterRootFromOneOptions(options),\n routePaths: routeIndex.getPaths(),\n preloads\n });\n }\n },\n hotUpdate(param) {\n var { file } = param;\n if (this.environment.name !== \"worker\") return;\n var graph = this.environment.moduleGraph;\n var entry = graph.getModuleById(resolvedWorkerdDevEntryId);\n if (!entry) return;\n var modules = graph.getModulesByFile(file);\n if (!(modules === null || modules === void 0 ? void 0 : modules.size)) return;\n graph.invalidateModule(entry);\n }\n };\n var cloudflarePlugins = cloudflare({\n configPath: wranglerInputPath,\n viteEnvironment: {\n name: \"worker\"\n }\n }).map(serveOnly);\n return [\n preparePlugin,\n virtualPlugin,\n ...cloudflarePlugins\n ];\n}\nexport {\n createWorkerdDevPlugins,\n generateWorkerdDevEntryModule,\n shouldEnableWorkerdDev,\n workerdDevEntryId\n};\n//# sourceMappingURL=workerdDevPlugin.js.map\n"],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
18
18
|
case artwork
|
|
19
19
|
case unknownPlayer
|
|
20
20
|
case rate
|
|
21
|
+
case replaced
|
|
21
22
|
|
|
22
23
|
var errorDescription: String? {
|
|
23
24
|
switch self {
|
|
@@ -33,6 +34,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
33
34
|
case .artwork: return "now playing artwork must be an existing image file"
|
|
34
35
|
case .unknownPlayer: return "the audio player id is not active"
|
|
35
36
|
case .rate: return "the playback rate must be within 0 to 2"
|
|
37
|
+
case .replaced: return "playback was replaced before it was ready"
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
40
|
}
|
|
@@ -51,6 +53,12 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
51
53
|
private var nowPlayingInfo: AudioNowPlayingInfo?
|
|
52
54
|
private var nowPlayingArtwork: UIImage?
|
|
53
55
|
private var remoteTargets: [(MPRemoteCommand, Any)] = []
|
|
56
|
+
// one now playing session at a time, owned by the singleton or by one
|
|
57
|
+
// managed player. owners clear only their own claim, so an old owner's
|
|
58
|
+
// cleanup never clears a newer one.
|
|
59
|
+
private var nowPlayingOwner: NowPlayingOwner?
|
|
60
|
+
private var ownerObservations: [NSKeyValueObservation] = []
|
|
61
|
+
private var pendingLoad: PendingLoad?
|
|
54
62
|
private var remoteCommandListeners: [UUID: (AudioRemoteCommandEvent) -> Void] = [:]
|
|
55
63
|
|
|
56
64
|
private final class ManagedAudioPlayer {
|
|
@@ -73,6 +81,24 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
73
81
|
|
|
74
82
|
private var managedPlayers: [String: ManagedAudioPlayer] = [:]
|
|
75
83
|
|
|
84
|
+
private enum NowPlayingOwner: Equatable {
|
|
85
|
+
case global
|
|
86
|
+
case managed(String)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// a singleton play with a position or paused flag: it resolves after the
|
|
90
|
+
// item is ready and the seek lands, before any sound.
|
|
91
|
+
private final class PendingLoad {
|
|
92
|
+
let promise: Promise<AudioPlaybackStatus>
|
|
93
|
+
let positionMs: Double
|
|
94
|
+
var seeking = false
|
|
95
|
+
|
|
96
|
+
init(promise: Promise<AudioPlaybackStatus>, positionMs: Double) {
|
|
97
|
+
self.promise = promise
|
|
98
|
+
self.positionMs = positionMs
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
76
102
|
override init() {
|
|
77
103
|
super.init()
|
|
78
104
|
interruptionObserver = NotificationCenter.default.addObserver(
|
|
@@ -121,38 +147,102 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
121
147
|
return promise
|
|
122
148
|
}
|
|
123
149
|
|
|
124
|
-
func play(uri: String) throws -> Promise<AudioPlaybackStatus> {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
try session.setActive(true)
|
|
134
|
-
self.clearPlayer()
|
|
135
|
-
let item = AVPlayerItem(url: url)
|
|
136
|
-
let player = AVPlayer(playerItem: item)
|
|
137
|
-
self.player = player
|
|
138
|
-
self.playerStatusObservation = player.observe(\.timeControlStatus, options: [.new]) {
|
|
139
|
-
[weak self] _, _ in
|
|
140
|
-
DispatchQueue.main.async { self?.syncNowPlaying() }
|
|
141
|
-
}
|
|
142
|
-
self.itemStatusObservation = item.observe(\.status, options: [.new]) { [weak self] _, _ in
|
|
143
|
-
DispatchQueue.main.async { self?.syncNowPlaying() }
|
|
150
|
+
func play(uri: String, options: AudioPlayOptions) throws -> Promise<AudioPlaybackStatus> {
|
|
151
|
+
let promise = Promise<AudioPlaybackStatus>()
|
|
152
|
+
DispatchQueue.main.async {
|
|
153
|
+
do {
|
|
154
|
+
if let status = try self.startPlayback(uri: uri, options: options, promise: promise) {
|
|
155
|
+
promise.resolve(withResult: status)
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
promise.reject(withError: Self.failure("play", error))
|
|
144
159
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
160
|
+
}
|
|
161
|
+
return promise
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// returns the status to resolve now, or nil when a prepared load resolves
|
|
165
|
+
// the promise later.
|
|
166
|
+
private func startPlayback(
|
|
167
|
+
uri: String, options: AudioPlayOptions, promise: Promise<AudioPlaybackStatus>
|
|
168
|
+
) throws -> AudioPlaybackStatus? {
|
|
169
|
+
guard self.recorder == nil else { throw Problem.busy }
|
|
170
|
+
let url = try Self.audioURL(uri)
|
|
171
|
+
if url.isFileURL && !FileManager.default.fileExists(atPath: url.path) {
|
|
172
|
+
throw Problem.missingFile
|
|
173
|
+
}
|
|
174
|
+
let prepare = options.positionMs != nil || options.paused != nil
|
|
175
|
+
let positionMs = options.positionMs ?? 0
|
|
176
|
+
guard positionMs.isFinite && positionMs >= 0 else { throw Problem.position }
|
|
177
|
+
let session = AVAudioSession.sharedInstance()
|
|
178
|
+
try session.setCategory(.playback, mode: .default)
|
|
179
|
+
try session.setActive(true)
|
|
180
|
+
self.clearPlayer()
|
|
181
|
+
let item = AVPlayerItem(url: url)
|
|
182
|
+
let player = AVPlayer(playerItem: item)
|
|
183
|
+
self.player = player
|
|
184
|
+
self.playerStatusObservation = player.observe(\.timeControlStatus, options: [.new]) {
|
|
185
|
+
[weak self] _, _ in
|
|
186
|
+
DispatchQueue.main.async { self?.syncNowPlaying() }
|
|
187
|
+
}
|
|
188
|
+
self.itemStatusObservation = item.observe(\.status, options: [.new]) { [weak self] _, _ in
|
|
189
|
+
DispatchQueue.main.async {
|
|
190
|
+
self?.advanceLoad()
|
|
152
191
|
self?.syncNowPlaying()
|
|
153
192
|
}
|
|
154
|
-
|
|
155
|
-
|
|
193
|
+
}
|
|
194
|
+
self.playerURI = url.absoluteString
|
|
195
|
+
self.playbackPaused = options.paused ?? false
|
|
196
|
+
self.playbackEnded = false
|
|
197
|
+
self.endObserver = NotificationCenter.default.addObserver(
|
|
198
|
+
forName: AVPlayerItem.didPlayToEndTimeNotification, object: item, queue: .main
|
|
199
|
+
) { [weak self] _ in
|
|
200
|
+
self?.playbackEnded = true
|
|
201
|
+
self?.syncNowPlaying()
|
|
202
|
+
}
|
|
203
|
+
if prepare {
|
|
204
|
+
self.pendingLoad = PendingLoad(promise: promise, positionMs: positionMs)
|
|
205
|
+
self.advanceLoad()
|
|
206
|
+
return nil
|
|
207
|
+
}
|
|
208
|
+
player.play()
|
|
209
|
+
return self.playbackStatus()
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// moves a prepared load forward once its item settles: seek exactly to
|
|
213
|
+
// the position, then play unless paused. replacement or stop rejects the
|
|
214
|
+
// load in clearPlayer, so a late completion finds a different load and
|
|
215
|
+
// does nothing.
|
|
216
|
+
private func advanceLoad() {
|
|
217
|
+
guard let load = pendingLoad, !load.seeking, let player, let item = player.currentItem
|
|
218
|
+
else { return }
|
|
219
|
+
switch item.status {
|
|
220
|
+
case .failed:
|
|
221
|
+
pendingLoad = nil
|
|
222
|
+
load.promise.reject(withError: Self.failure("play", item.error ?? Problem.state))
|
|
223
|
+
case .readyToPlay:
|
|
224
|
+
load.seeking = true
|
|
225
|
+
var seconds = load.positionMs / 1000
|
|
226
|
+
let duration = item.duration.seconds
|
|
227
|
+
if duration.isFinite && duration >= 0 { seconds = min(seconds, duration) }
|
|
228
|
+
player.seek(
|
|
229
|
+
to: CMTime(seconds: seconds, preferredTimescale: 600),
|
|
230
|
+
toleranceBefore: .zero, toleranceAfter: .zero
|
|
231
|
+
) { [weak self] finished in
|
|
232
|
+
DispatchQueue.main.async {
|
|
233
|
+
guard let self, self.pendingLoad === load else { return }
|
|
234
|
+
self.pendingLoad = nil
|
|
235
|
+
guard finished, self.player === player else {
|
|
236
|
+
load.promise.reject(withError: Self.failure("play", Problem.state))
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
if !self.playbackPaused { player.play() }
|
|
240
|
+
self.syncNowPlaying()
|
|
241
|
+
load.promise.resolve(withResult: self.playbackStatus())
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
default:
|
|
245
|
+
return
|
|
156
246
|
}
|
|
157
247
|
}
|
|
158
248
|
|
|
@@ -178,7 +268,8 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
178
268
|
self.playbackEnded = false
|
|
179
269
|
}
|
|
180
270
|
self.playbackPaused = false
|
|
181
|
-
|
|
271
|
+
// a prepared load plays itself once its seek lands.
|
|
272
|
+
if self.pendingLoad == nil { player.play() }
|
|
182
273
|
self.syncNowPlaying()
|
|
183
274
|
return self.playbackStatus()
|
|
184
275
|
}
|
|
@@ -191,7 +282,9 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
191
282
|
promise.reject(withError: Self.failure("seek", Problem.position))
|
|
192
283
|
return
|
|
193
284
|
}
|
|
194
|
-
guard let player = self.player, player.currentItem?.status == .readyToPlay
|
|
285
|
+
guard let player = self.player, player.currentItem?.status == .readyToPlay,
|
|
286
|
+
self.pendingLoad == nil
|
|
287
|
+
else {
|
|
195
288
|
promise.reject(withError: Self.failure("seek", Problem.state))
|
|
196
289
|
return
|
|
197
290
|
}
|
|
@@ -311,43 +404,29 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
311
404
|
func setNowPlayingInfo(info: AudioNowPlayingInfo) throws -> Promise<Void> {
|
|
312
405
|
perform("setNowPlayingInfo") {
|
|
313
406
|
guard let player = self.player else { throw Problem.state }
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
var artwork: UIImage?
|
|
318
|
-
if let artworkUri = info.artworkUri {
|
|
319
|
-
guard let url = URL(string: artworkUri), url.isFileURL,
|
|
320
|
-
FileManager.default.fileExists(atPath: url.path),
|
|
321
|
-
let image = UIImage(contentsOfFile: url.path)
|
|
322
|
-
else { throw Problem.artwork }
|
|
323
|
-
artwork = image
|
|
324
|
-
}
|
|
325
|
-
if let session = self.nowPlayingSession, session.players.first === player {
|
|
326
|
-
self.nowPlayingInfo = info
|
|
327
|
-
self.nowPlayingArtwork = artwork
|
|
328
|
-
self.syncNowPlaying()
|
|
329
|
-
return
|
|
330
|
-
}
|
|
331
|
-
self.clearNowPlaying()
|
|
332
|
-
let session = MPNowPlayingSession(players: [player])
|
|
333
|
-
session.automaticallyPublishesNowPlayingInfo = false
|
|
334
|
-
self.nowPlayingSession = session
|
|
335
|
-
self.nowPlayingInfo = info
|
|
336
|
-
self.nowPlayingArtwork = artwork
|
|
337
|
-
self.installRemoteCommands(session.remoteCommandCenter)
|
|
338
|
-
self.syncNowPlaying()
|
|
339
|
-
session.becomeActiveIfPossible { [weak self, weak session] active in
|
|
340
|
-
guard active, let session else { return }
|
|
341
|
-
DispatchQueue.main.async { [weak self] in
|
|
342
|
-
guard let self, self.nowPlayingSession === session else { return }
|
|
343
|
-
self.syncNowPlaying()
|
|
344
|
-
}
|
|
345
|
-
}
|
|
407
|
+
let artwork = try Self.nowPlayingArtwork(info)
|
|
408
|
+
self.claimNowPlaying(.global, player: player, info: info, artwork: artwork)
|
|
346
409
|
}
|
|
347
410
|
}
|
|
348
411
|
|
|
349
412
|
func clearNowPlayingInfo() throws -> Promise<Void> {
|
|
350
|
-
perform("clearNowPlayingInfo") {
|
|
413
|
+
perform("clearNowPlayingInfo") {
|
|
414
|
+
if self.nowPlayingOwner == .global { self.clearNowPlaying() }
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
func setPlayerNowPlayingInfo(playerId: String, info: AudioNowPlayingInfo) throws -> Promise<Void> {
|
|
419
|
+
perform("setPlayerNowPlayingInfo") {
|
|
420
|
+
let managed = try self.managedPlayer(playerId)
|
|
421
|
+
let artwork = try Self.nowPlayingArtwork(info)
|
|
422
|
+
self.claimNowPlaying(.managed(playerId), player: managed.player, info: info, artwork: artwork)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
func clearPlayerNowPlayingInfo(playerId: String) throws -> Promise<Void> {
|
|
427
|
+
perform("clearPlayerNowPlayingInfo") {
|
|
428
|
+
if self.nowPlayingOwner == .managed(playerId) { self.clearNowPlaying() }
|
|
429
|
+
}
|
|
351
430
|
}
|
|
352
431
|
|
|
353
432
|
func addRemoteCommandListener(
|
|
@@ -381,16 +460,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
381
460
|
|
|
382
461
|
func playerPlay(playerId: String) throws -> Void {
|
|
383
462
|
try mainSync("playerPlay") {
|
|
384
|
-
|
|
385
|
-
let session = AVAudioSession.sharedInstance()
|
|
386
|
-
try session.setCategory(.playback, mode: .default)
|
|
387
|
-
try session.setActive(true)
|
|
388
|
-
if managed.ended {
|
|
389
|
-
managed.player.seek(to: .zero)
|
|
390
|
-
managed.ended = false
|
|
391
|
-
}
|
|
392
|
-
managed.paused = false
|
|
393
|
-
managed.player.rate = Float(managed.rate)
|
|
463
|
+
try self.startManaged(try self.managedPlayer(playerId))
|
|
394
464
|
}
|
|
395
465
|
}
|
|
396
466
|
|
|
@@ -399,6 +469,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
399
469
|
let managed = try self.managedPlayer(playerId)
|
|
400
470
|
managed.player.pause()
|
|
401
471
|
managed.paused = true
|
|
472
|
+
self.syncOwner(playerId)
|
|
402
473
|
}
|
|
403
474
|
}
|
|
404
475
|
|
|
@@ -426,6 +497,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
426
497
|
return
|
|
427
498
|
}
|
|
428
499
|
managed.ended = false
|
|
500
|
+
self.syncOwner(playerId)
|
|
429
501
|
promise.resolve()
|
|
430
502
|
}
|
|
431
503
|
}
|
|
@@ -450,6 +522,10 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
450
522
|
managed.paused = true
|
|
451
523
|
managed.ended = false
|
|
452
524
|
self.installPlayerEndObserver(id: playerId, managed: managed)
|
|
525
|
+
if self.nowPlayingOwner == .managed(playerId) {
|
|
526
|
+
self.observeOwner()
|
|
527
|
+
self.syncNowPlaying()
|
|
528
|
+
}
|
|
453
529
|
}
|
|
454
530
|
}
|
|
455
531
|
|
|
@@ -459,6 +535,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
459
535
|
return
|
|
460
536
|
}
|
|
461
537
|
guard let managed = managedPlayers.removeValue(forKey: playerId) else { return }
|
|
538
|
+
if nowPlayingOwner == .managed(playerId) { clearNowPlaying() }
|
|
462
539
|
clearPlayerEndObserver(managed)
|
|
463
540
|
managed.player.pause()
|
|
464
541
|
managed.player.replaceCurrentItem(with: nil)
|
|
@@ -518,6 +595,22 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
518
595
|
}
|
|
519
596
|
}
|
|
520
597
|
|
|
598
|
+
private func startManaged(_ managed: ManagedAudioPlayer) throws {
|
|
599
|
+
let session = AVAudioSession.sharedInstance()
|
|
600
|
+
try session.setCategory(.playback, mode: .default)
|
|
601
|
+
try session.setActive(true)
|
|
602
|
+
if managed.ended {
|
|
603
|
+
managed.player.seek(to: .zero)
|
|
604
|
+
managed.ended = false
|
|
605
|
+
}
|
|
606
|
+
managed.paused = false
|
|
607
|
+
managed.player.rate = Float(managed.rate)
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
private func syncOwner(_ playerId: String) {
|
|
611
|
+
if nowPlayingOwner == .managed(playerId) { syncNowPlaying() }
|
|
612
|
+
}
|
|
613
|
+
|
|
521
614
|
private func managedPlayer(_ id: String) throws -> ManagedAudioPlayer {
|
|
522
615
|
guard let managed = managedPlayers[id] else { throw Problem.unknownPlayer }
|
|
523
616
|
return managed
|
|
@@ -587,6 +680,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
587
680
|
}
|
|
588
681
|
} else {
|
|
589
682
|
managed.ended = true
|
|
683
|
+
self.syncOwner(id)
|
|
590
684
|
}
|
|
591
685
|
}
|
|
592
686
|
}
|
|
@@ -640,6 +734,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
640
734
|
let duration = item.duration.seconds
|
|
641
735
|
let state: AudioPlaybackState
|
|
642
736
|
if item.status == .failed { state = .failed }
|
|
737
|
+
else if pendingLoad != nil { state = .loading }
|
|
643
738
|
else if playbackEnded { state = .ended }
|
|
644
739
|
else if playbackPaused { state = .paused }
|
|
645
740
|
else if item.status != .readyToPlay || player.timeControlStatus == .waitingToPlayAtSpecifiedRate {
|
|
@@ -690,9 +785,9 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
690
785
|
|
|
691
786
|
private func handleRemoteToggle() -> MPRemoteCommandHandlerStatus {
|
|
692
787
|
if !Thread.isMainThread { return DispatchQueue.main.sync { self.handleRemoteToggle() } }
|
|
693
|
-
guard let player else { return .noSuchContent }
|
|
788
|
+
guard let player = ownerPlayer() else { return .noSuchContent }
|
|
694
789
|
return handleRemoteCommand(
|
|
695
|
-
|
|
790
|
+
ownerPaused() || player.timeControlStatus != .playing ? .play : .pause)
|
|
696
791
|
}
|
|
697
792
|
|
|
698
793
|
private func handleRemoteCommand(
|
|
@@ -701,33 +796,143 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
701
796
|
if !Thread.isMainThread {
|
|
702
797
|
return DispatchQueue.main.sync { self.handleRemoteCommand(type, positionMs: positionMs) }
|
|
703
798
|
}
|
|
704
|
-
guard
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
case .
|
|
711
|
-
player.
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
799
|
+
guard nowPlayingSession != nil, let owner = nowPlayingOwner else { return .noSuchContent }
|
|
800
|
+
if type == .seek {
|
|
801
|
+
guard let positionMs, positionMs.isFinite, positionMs >= 0 else { return .commandFailed }
|
|
802
|
+
}
|
|
803
|
+
var playerId: String?
|
|
804
|
+
switch owner {
|
|
805
|
+
case .global:
|
|
806
|
+
guard let player else { return .noSuchContent }
|
|
807
|
+
switch type {
|
|
808
|
+
case .play:
|
|
809
|
+
if playbackEnded { player.seek(to: .zero); playbackEnded = false }
|
|
810
|
+
playbackPaused = false
|
|
811
|
+
if pendingLoad == nil { player.play() }
|
|
812
|
+
case .pause:
|
|
813
|
+
player.pause()
|
|
814
|
+
playbackPaused = true
|
|
815
|
+
case .seek:
|
|
816
|
+
guard pendingLoad == nil else { return .commandFailed }
|
|
817
|
+
seekOwner(player, positionMs: positionMs!)
|
|
818
|
+
playbackEnded = false
|
|
716
819
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
820
|
+
case .managed(let id):
|
|
821
|
+
guard let managed = managedPlayers[id] else { return .noSuchContent }
|
|
822
|
+
playerId = id
|
|
823
|
+
switch type {
|
|
824
|
+
case .play:
|
|
825
|
+
do { try startManaged(managed) } catch { return .commandFailed }
|
|
826
|
+
case .pause:
|
|
827
|
+
managed.player.pause()
|
|
828
|
+
managed.paused = true
|
|
829
|
+
case .seek:
|
|
830
|
+
guard managed.player.currentItem?.status == .readyToPlay else { return .commandFailed }
|
|
831
|
+
seekOwner(managed.player, positionMs: positionMs!)
|
|
832
|
+
managed.ended = false
|
|
720
833
|
}
|
|
721
|
-
playbackEnded = false
|
|
722
834
|
}
|
|
723
835
|
syncNowPlaying()
|
|
724
|
-
let event = AudioRemoteCommandEvent(type: type, positionMs: positionMs)
|
|
836
|
+
let event = AudioRemoteCommandEvent(type: type, positionMs: positionMs, playerId: playerId)
|
|
725
837
|
for listener in Array(remoteCommandListeners.values) { listener(event) }
|
|
726
838
|
return .success
|
|
727
839
|
}
|
|
728
840
|
|
|
841
|
+
private func seekOwner(_ player: AVPlayer, positionMs: Double) {
|
|
842
|
+
player.seek(to: CMTime(seconds: positionMs / 1000, preferredTimescale: 600)) {
|
|
843
|
+
[weak self] _ in
|
|
844
|
+
DispatchQueue.main.async { self?.syncNowPlaying() }
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
private func ownerPlayer() -> AVPlayer? {
|
|
849
|
+
switch nowPlayingOwner {
|
|
850
|
+
case .global: return player
|
|
851
|
+
case .managed(let id): return managedPlayers[id]?.player
|
|
852
|
+
case nil: return nil
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
private func ownerPaused() -> Bool {
|
|
857
|
+
switch nowPlayingOwner {
|
|
858
|
+
case .global: return playbackPaused
|
|
859
|
+
case .managed(let id): return managedPlayers[id]?.paused ?? true
|
|
860
|
+
case nil: return true
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
private func ownerEnded() -> Bool {
|
|
865
|
+
switch nowPlayingOwner {
|
|
866
|
+
case .global: return playbackEnded
|
|
867
|
+
case .managed(let id): return managedPlayers[id]?.ended ?? false
|
|
868
|
+
case nil: return false
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
private static func nowPlayingArtwork(_ info: AudioNowPlayingInfo) throws -> UIImage? {
|
|
873
|
+
guard !info.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
|
|
874
|
+
throw Problem.metadata
|
|
875
|
+
}
|
|
876
|
+
guard let artworkUri = info.artworkUri else { return nil }
|
|
877
|
+
guard let url = URL(string: artworkUri), url.isFileURL,
|
|
878
|
+
FileManager.default.fileExists(atPath: url.path),
|
|
879
|
+
let image = UIImage(contentsOfFile: url.path)
|
|
880
|
+
else { throw Problem.artwork }
|
|
881
|
+
return image
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// a claim for the session's own player keeps it. a transfer to another
|
|
885
|
+
// player starts a session for that player and publishes the new card in
|
|
886
|
+
// the same pass, without clearing the old one first. swapping players on
|
|
887
|
+
// one session raised an objective-c exception on the ios 27 simulator.
|
|
888
|
+
private func claimNowPlaying(
|
|
889
|
+
_ owner: NowPlayingOwner, player: AVPlayer, info: AudioNowPlayingInfo, artwork: UIImage?
|
|
890
|
+
) {
|
|
891
|
+
nowPlayingInfo = info
|
|
892
|
+
nowPlayingArtwork = artwork
|
|
893
|
+
nowPlayingOwner = owner
|
|
894
|
+
let session: MPNowPlayingSession
|
|
895
|
+
if let current = nowPlayingSession, current.players.count == 1,
|
|
896
|
+
current.players[0] === player
|
|
897
|
+
{
|
|
898
|
+
session = current
|
|
899
|
+
} else {
|
|
900
|
+
for (command, target) in remoteTargets { command.removeTarget(target) }
|
|
901
|
+
session = MPNowPlayingSession(players: [player])
|
|
902
|
+
session.automaticallyPublishesNowPlayingInfo = false
|
|
903
|
+
nowPlayingSession = session
|
|
904
|
+
installRemoteCommands(session.remoteCommandCenter)
|
|
905
|
+
}
|
|
906
|
+
observeOwner()
|
|
907
|
+
syncNowPlaying()
|
|
908
|
+
session.becomeActiveIfPossible { [weak self, weak session] active in
|
|
909
|
+
guard active, let session else { return }
|
|
910
|
+
DispatchQueue.main.async { [weak self] in
|
|
911
|
+
guard let self, self.nowPlayingSession === session else { return }
|
|
912
|
+
self.syncNowPlaying()
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
private func observeOwner() {
|
|
918
|
+
ownerObservations.forEach { $0.invalidate() }
|
|
919
|
+
ownerObservations.removeAll()
|
|
920
|
+
guard let player = ownerPlayer() else { return }
|
|
921
|
+
ownerObservations.append(
|
|
922
|
+
player.observe(\.timeControlStatus, options: [.new]) { [weak self] _, _ in
|
|
923
|
+
DispatchQueue.main.async { self?.syncNowPlaying() }
|
|
924
|
+
})
|
|
925
|
+
if let item = player.currentItem {
|
|
926
|
+
ownerObservations.append(
|
|
927
|
+
item.observe(\.status, options: [.new]) { [weak self] _, _ in
|
|
928
|
+
DispatchQueue.main.async { self?.syncNowPlaying() }
|
|
929
|
+
})
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
729
933
|
private func syncNowPlaying() {
|
|
730
|
-
guard let session = nowPlayingSession, let info = nowPlayingInfo, let player
|
|
934
|
+
guard let session = nowPlayingSession, let info = nowPlayingInfo, let player = ownerPlayer()
|
|
935
|
+
else { return }
|
|
731
936
|
let position = player.currentTime().seconds
|
|
732
937
|
let duration = player.currentItem?.duration.seconds ?? .nan
|
|
733
938
|
var metadata: [String: Any] = [
|
|
@@ -735,7 +940,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
735
940
|
MPNowPlayingInfoPropertyMediaType: MPNowPlayingInfoMediaType.audio.rawValue,
|
|
736
941
|
MPNowPlayingInfoPropertyElapsedPlaybackTime: position.isFinite ? max(0, position) : 0,
|
|
737
942
|
MPNowPlayingInfoPropertyPlaybackRate:
|
|
738
|
-
!
|
|
943
|
+
!ownerEnded() && player.timeControlStatus == .playing ? player.rate : 0.0,
|
|
739
944
|
MPNowPlayingInfoPropertyDefaultPlaybackRate: 1.0,
|
|
740
945
|
]
|
|
741
946
|
if let artist = info.artist { metadata[MPMediaItemPropertyArtist] = artist }
|
|
@@ -756,10 +961,17 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
756
961
|
nowPlayingSession = nil
|
|
757
962
|
nowPlayingInfo = nil
|
|
758
963
|
nowPlayingArtwork = nil
|
|
964
|
+
nowPlayingOwner = nil
|
|
965
|
+
ownerObservations.forEach { $0.invalidate() }
|
|
966
|
+
ownerObservations.removeAll()
|
|
759
967
|
}
|
|
760
968
|
|
|
761
969
|
private func clearPlayer() {
|
|
762
|
-
clearNowPlaying()
|
|
970
|
+
if nowPlayingOwner == .global { clearNowPlaying() }
|
|
971
|
+
if let load = pendingLoad {
|
|
972
|
+
pendingLoad = nil
|
|
973
|
+
load.promise.reject(withError: Self.failure("play", Problem.replaced))
|
|
974
|
+
}
|
|
763
975
|
playerStatusObservation?.invalidate()
|
|
764
976
|
playerStatusObservation = nil
|
|
765
977
|
itemStatusObservation?.invalidate()
|
|
@@ -818,6 +1030,7 @@ final class HybridOneAudio: HybridOneAudioSpec {
|
|
|
818
1030
|
case Problem.artwork: code = "E_AUDIO_ARTWORK"
|
|
819
1031
|
case Problem.unknownPlayer: code = "E_AUDIO_STATE"
|
|
820
1032
|
case Problem.rate: code = "E_AUDIO_RATE"
|
|
1033
|
+
case Problem.replaced: code = "E_AUDIO_STATE"
|
|
821
1034
|
default: code = "E_AUDIO_FAILED"
|
|
822
1035
|
}
|
|
823
1036
|
return oneNativeError(code, "Audio.\(verb): \(error.localizedDescription)")
|