rollup-plugin-rld
Version:
Rollup plugin to inject a live reload script into your bundle
1 lines • 10.3 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/lib/createEmitter.ts","../src/utils/logSuccess.util.ts","../src/lib/createServer.ts","../src/lib/injectable.ts","../src/index.ts"],"sourcesContent":["/** @format */\nimport type { Emitter, EmitterAction, EmitChanges, Subscribe } from '../types';\n\n/**\n * @description\n * Creates a simple emitter to emit changes to subscribers.\n *\n * @returns { Emitter } an emitter that can be used to subscribe and emit changes.\n */\n\nexport const createEmitter = (): Emitter => {\n const subscribers: Array<{ action: EmitterAction }> = [];\n\n // Method used to notify subscribers\n const emit: EmitChanges = () => subscribers.forEach(({ action }) => action());\n\n // Method used to reset the subscription list\n const reset = () => {\n subscribers.length = 0;\n };\n\n // Method used to subscribe\n const subscribe: Subscribe = (action: EmitterAction) => {\n subscribers.push({ action });\n };\n\n return {\n emit,\n reset,\n subscribe,\n };\n};\n","/** @format */\n\n/**\n * @description\n * Utility function to style a console message and prepend a identifier.\n *\n * @param { string } text - the text to log.\n * @returns { string } the created string.\n */\n\nexport const logSuccess = (text: string): string => `\\x1b[32m🚀 @Rollup-Plugin-Rld: ${text}\\x1b[0m`;\n","/** @format */\n\nimport http, { Server } from 'node:http';\nimport type { ServerInit } from '../types';\nimport { logSuccess } from '../utils/logSuccess.util';\n\n/**\n * @description\n * Function to create a HTTPServer that listens to a passed url and sends a event inside a\n * subscription of the passed emitter. This way, reloads can be triggered remotely.\n *\n * @param { ServerInit } serverInit - configuration object to pass the url and emitter to the server.\n * @returns { Server } the created HTTPServer\n */\n\nexport const createServer = (serverInit: ServerInit): Server => {\n return http.createServer(async (req, res) => {\n let { emitter, url } = serverInit;\n\n // if the passed url is different from the request url,\n // cancel the request.\n if (req.url !== url) return;\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Access-Control-Allow-Origin': '*',\n });\n\n // reset the emitter and add a new subscription\n // when the emitter emits, the server event will be send and the\n // page will reload\n emitter.reset();\n emitter.subscribe(() => {\n console.log(logSuccess(`Reloading...`));\n res.write('data: { \"rld\": \"true\" }\\n\\n');\n });\n });\n};\n","/** @format */\n\nexport const injectable = (port: number | string, host: string, url: string, attributes: string, log: boolean) => {\n // Return early if there is no window or document or the script tag already exists.\n if (!window || !document) return;\n if (document.head.querySelector(`[url='${url}']`)) return;\n\n const script = document.createElement('script');\n Object.entries(JSON.parse(attributes) as Record<string, string>).forEach(([key, value]) =>\n script.setAttribute(key, value)\n );\n script.setAttribute('url', url);\n script.textContent = `new EventSource('http://${host}:${port}${url}').addEventListener('message', (ev) => \n JSON.parse(ev.data).rld && window.navigation.reload())\n ${log ? `console.log('[Rollup-Plugin-Rld]: Reloaded...');` : ''}`;\n\n\n // Inject a comment before the script tag to mark the script as useful\n document.head.appendChild(document.createComment(' Script injected by Rollup-Plugin-Rld '));\n document.head.appendChild(script);\n};\n","/** @format */\n\nimport type { Plugin, RollupOptions } from 'rollup';\nimport type { Server } from 'node:http';\nimport { createEmitter } from './lib/createEmitter';\nimport { createServer } from './lib/createServer';\nimport { injectable } from './lib/injectable';\nimport type { RldInit } from './types';\n\n/**\n * @description\n * Factory function to create the Plugin object from the passed init / defaults.\n * `Rollup-Plugin-Rld` will inject a function into your bundle when Rollup is used in watch mode.\n * The function itself will inject a script tag if executed in a HTML instance, that will listen to\n * the server created by the plugin. If changes to the bundle are detected, a reload will be triggered.\n *\n * @param { Partial<RldInit> } init - The optional init Object for the Plugin.\n * @returns { Plugin } the Plugin object.\n */\n\nexport const rld = (init: Partial<RldInit> = {}): Plugin => {\n // Parse the user provided initialization object into the defaults.\n const config = { port: 31415, host: 'localhost', url: '/rld', log: false, ...init };\n // normalize config.url parameter to ensure correct url param\n config.url = config.url[0] === '/' ? config.url : '/' + config.url;\n\n const emitter = createEmitter();\n let watch = false;\n let server: Server | null = null;\n\n return {\n name: 'Rollup-Plugin-Rld',\n\n /**\n * Use the `options` hook to determine if rollup is in\n * watch mode or not.\n */\n async options(options: RollupOptions) {\n watch = !!options.watch;\n },\n\n /**\n * The `buildStart` hook is used to create the server if it\n * does not already exist and the bundler is not in watch mode.\n */\n async buildStart() {\n if (server || !watch) return;\n\n server = createServer({ emitter, url: config.url });\n server.listen(config.port, config.host);\n server.on('error', (err) => {\n console.log({ err });\n });\n },\n\n /**\n * The `buildEnd` hook is used to emit the reload event.\n */\n async buildEnd() {\n if (!watch) return;\n emitter.emit();\n },\n\n /**\n * The `closeWatcher` hoo is used to close the server so as to not leave any\n * unterminated servers.\n */\n async closeWatcher() {\n if (server) server.close();\n },\n\n /**\n * Use the `transform` hook to inject the bundle in watch mode into the entry\n * module.\n */\n async transform(code, module) {\n if (!watch || !this.getModuleInfo(module)?.isEntry) return code;\n return (\n `(${injectable.toString()})(${config.port}, '${config.host}', '${config.url}', '${JSON.stringify(\n config.attributes || {}\n )}', ${config.log});\\n` + code\n );\n },\n };\n};\n"],"names":[],"mappings":"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"}