extend-chrome / messages Goto Github PK
View Code? Open in Web Editor NEWAn API for Chrome Extension messages that makes sense.
Home Page: https://www.npmjs.com/package/@extend-chrome/messages
License: MIT License
An API for Chrome Extension messages that makes sense.
Home Page: https://www.npmjs.com/package/@extend-chrome/messages
License: MIT License
Hello again! Following up the discussion at crxjs/chrome-extension-tools#124. I'm now trying to use @extend-chome/messages
and the built file ends up importing another file like this:
import { s as sendNumber } from './chunks/messages-2397a427.js';
This, in turn, throws Cannot use import statement outside a module
. As you already may know from the linked issue, content-script.ts
was added as an input file in rollup.config.js
. I tried returning an array from rollup config by having a configuration for content-script.ts
and another for manifest.ts
and that kind of works but simpleReloader
is now working right.
rollup.config.js looks like this:
import path from 'path'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
import { chromeExtension, simpleReloader } from 'rollup-plugin-chrome-extension'
import { emptyDir } from 'rollup-plugin-empty-dir'
import zip from 'rollup-plugin-zip'
import replace from '@rollup/plugin-replace'
const isProduction = process.env.NODE_ENV === 'production'
export default {
input: ['src/manifest.ts', 'src/content-script.ts'],
output: {
dir: 'dist',
format: 'esm',
chunkFileNames: path.join('chunks', '[name]-[hash].js'),
},
plugins: [
replace({
'process.env.NODE_ENV': isProduction
? JSON.stringify('production')
: JSON.stringify('development'),
preventAssignment: true,
}),
chromeExtension(),
// Adds a Chrome extension reloader during watch mode
simpleReloader(),
resolve(),
commonjs(),
typescript(),
// Empties the output dir before a new build
emptyDir(),
// Outputs a zip file in ./releases
isProduction && zip({ dir: 'releases' }),
],
}
Thank you!
First and foremost, this project is amazing and a real lifesaver for my app.
I'm trying to await a response from the getMessage API but can't seem to find a way to do it. Using the messages API I can, but I'm unsure how to use typescript to guard the payload with it. How can I leverage the ability to send a response, while also leveraging the ability to type check payloads?
For example:
import { getMessage } from '@extend-chrome/messages';
interface Payload {
arg: 1;
}
export const [sendReady, readyStream, waitForReady] = getMessage<Payload>('READY');
// background
sendReady.then((response) => console.log(response)); // { ping: true }
// content
readyStream.subscribe(([{ arg }, sender], sendResponse)) => {
sendResponse({ ping: true });
OR
return { ping: true };
});
Thank you!
I'd like to send message from background/popup to specific content tab
I'd like send
method can handle option.tabId
Or another method send*ToContent(tab.id, payload, options)
I have explained the problem in great detail over on stack overflow over here.
To describe here also in brief I am trying to send a URL object from background script to content script. The example in the documentation is from content script to background script. Anyways i tried to do the same shown in the documentation for background script to content script but there is error is console saying
Could not establish connection. Receiving end does not exist
Here is the copy of stackoverflow question which has all info
I have my background script like this
import { sendUrlInfo, waitForUrl } from 'utils/messaging';
import URL from 'url-parse';
chrome.webNavigation.onHistoryStateUpdated.addListener((details) => {
const url = new URL(details.url);
console.log('sending', url.hostname, url.pathname);
sendUrlInfo(new URL(details.url));
});
chrome.webNavigation.onCompleted.addListener((details) => {
if (details.url !== 'about:blank') {
const url = new URL(details.url);
console.log('sending', url.hostname, url.pathname);
sendUrlInfo(new URL(details.url));
}
});
And according to documentation i have message.js as shown below
import { getMessage } from '@extend-chrome/messages';
import URL from 'url-parse';
const messageTypes = {
URL_INFO: 'URL_INFO',
};
export const [sendUrlInfo, urlStream, waitForUrl] = getMessage<URL>(
messageTypes.URL_INFO,
);
and now content script I have written in react
So i am trying to subscribe to stream when the component is mounted
import React, { useState, useEffect, useRef } from 'react';
import Editor from 'content/components/Editor';
import Opener from 'content/components/Opener';
import { urlStream, waitForUrl } from 'utils/messaging';
const Main: React.FC = () => {
const [isOpen, setIsOpen] = useState(false);
const [showContent, setShowContent] = useState(false);
const editorRef = useRef<HTMLTextAreaElement | null>(null);
useEffect(() => {
console.log('MOunted');
urlStream.subscribe(([url]) => {
console.log('Received', url.hostname, url.pathname);
if (url.hostname === 'www.youtube.com' && url.pathname === '/watch') {
if (!showContent) setShowContent(true);
} else {
if (showContent) setShowContent(false);
}
});
}, []);
useEffect(() => {
document.addEventListener('keydown', onKeyPress);
return () => {
document.removeEventListener('keydown', onKeyPress);
};
});
const onKeyPress = (e: KeyboardEvent) => {
if (e.ctrlKey && e.which === 192) {
e.preventDefault();
setIsOpen(!isOpen);
}
};
if (!showContent) return <></>;
return (
<>
<div>test</div>
<Opener isOpen={isOpen} onClick={() => setIsOpen(true)} />
<Editor
isOpen={isOpen}
ref={editorRef}
onClose={() => setIsOpen(false)}
/>
</>
);
};
export default Main;
The error I am getting in background script console is
Could not establish connection. Receiving end does not exist
I think as much as i understand the background script is trying to send msg but the content script observable is not subscribed yet. As content script run after the page is loaded.
If this is the issue is there any way to use this library properly.
BTW this works if we use normal chrome api like this
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
chrome.tabs.sendMessage(
tabs[0].id,
message,
function () {
console.log("msg sent")
}
);
});
and use onMessage to receive the msg.
I only went through files here.
getMessage(...).wait will return the same i.e. [data, sender] tuple, as does firstValueFrom(getMessage(...).stream)
but the types are annotated incorrectly
const [_, stream, wait] = getMessage("a")
const waited = wait()
const streamed = firstValueFrom(stream)
the same type
the type infer to Promise and Promise<[string, chrome.runtime.MessageSender]> even though the output is the same
We're migrating this library over to a new and more aptly named organization: extend-chrome!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.