├── .nvmrc
├── .husky
├── .gitignore
├── pre-commit
└── commit-msg
├── CNAME
├── website
├── static
│ ├── .nojekyll
│ └── img
│ │ ├── slots.png
│ │ ├── favicon.ico
│ │ ├── hello-widget.png
│ │ ├── merkur-logo.png
│ │ ├── merkur-concept.jpg
│ │ ├── merkur-illustration.png
│ │ ├── merkur-integration-info.jpg
│ │ └── merkur-integration-lifecycle.png
├── src
│ ├── components
│ │ └── HomepageFeatures
│ │ │ └── styles.module.css
│ ├── pages
│ │ ├── index.module.css
│ │ ├── demo.module.css
│ │ └── index.tsx
│ └── css
│ │ └── custom.css
├── tsconfig.json
├── .gitignore
├── README.md
├── sidebars.ts
└── package.json
├── packages
├── create-widget
│ ├── template
│ │ ├── .nvmrc
│ │ ├── jest.setup.js
│ │ ├── server
│ │ │ ├── config
│ │ │ │ ├── test.json
│ │ │ │ ├── default.json
│ │ │ │ └── production.json
│ │ │ ├── routes
│ │ │ │ ├── error
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── error.js
│ │ │ │ └── widgetAPI
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── widgetAPI.js
│ │ │ ├── __integration__
│ │ │ │ └── appSpec.js
│ │ │ ├── server.js
│ │ │ └── app.js
│ │ ├── .eslintrc.js
│ │ ├── .prettierignore
│ │ ├── merkur.config.mjs
│ │ ├── jest.config.js
│ │ ├── jsconfig.json
│ │ ├── src
│ │ │ ├── style.css
│ │ │ └── widget.js
│ │ └── package.json
│ ├── .npmrc
│ ├── views
│ │ ├── preact
│ │ │ ├── template
│ │ │ │ ├── jest.setup.js
│ │ │ │ ├── src
│ │ │ │ │ ├── components
│ │ │ │ │ │ ├── WidgetContext.js
│ │ │ │ │ │ ├── WidgetDescription.jsx
│ │ │ │ │ │ ├── Welcome.jsx
│ │ │ │ │ │ └── Counter.jsx
│ │ │ │ │ ├── views
│ │ │ │ │ │ ├── ErrorView.jsx
│ │ │ │ │ │ ├── View.jsx
│ │ │ │ │ │ └── __tests__
│ │ │ │ │ │ │ └── ViewSpec.jsx
│ │ │ │ │ ├── slots
│ │ │ │ │ │ └── HeadlineSlot.jsx
│ │ │ │ │ └── widget.js
│ │ │ │ ├── .eslintrc.js
│ │ │ │ ├── merkur.config.mjs
│ │ │ │ └── jest.config.js
│ │ │ └── template.json
│ │ ├── vanilla
│ │ │ ├── template.json
│ │ │ └── template
│ │ │ │ └── src
│ │ │ │ ├── components
│ │ │ │ ├── WidgetDescription.js
│ │ │ │ ├── Welcome.js
│ │ │ │ └── Counter.js
│ │ │ │ ├── views
│ │ │ │ ├── ErrorView.js
│ │ │ │ └── View.js
│ │ │ │ ├── entries
│ │ │ │ ├── server.js
│ │ │ │ └── client.js
│ │ │ │ └── slots
│ │ │ │ └── HeadlineSlot.js
│ │ ├── svelte
│ │ │ ├── template.json
│ │ │ └── template
│ │ │ │ ├── merkur.config.mjs
│ │ │ │ ├── src
│ │ │ │ ├── components
│ │ │ │ │ ├── WidgetDescription.svelte
│ │ │ │ │ ├── Welcome.svelte
│ │ │ │ │ └── Counter.svelte
│ │ │ │ ├── views
│ │ │ │ │ ├── ErrorView.svelte
│ │ │ │ │ └── View.svelte
│ │ │ │ ├── slots
│ │ │ │ │ └── HeadlineSlot.svelte
│ │ │ │ └── widget.js
│ │ │ │ └── webpack.config.js
│ │ └── uhtml
│ │ │ ├── template.json
│ │ │ └── template
│ │ │ ├── merkur.config.mjs
│ │ │ ├── src
│ │ │ ├── components
│ │ │ │ ├── WidgetDescription.js
│ │ │ │ ├── Welcome.js
│ │ │ │ └── Counter.js
│ │ │ ├── views
│ │ │ │ ├── ErrorView.js
│ │ │ │ └── View.js
│ │ │ ├── slots
│ │ │ │ └── HeadlineSlot.js
│ │ │ └── widget.js
│ │ │ └── webpack.config.js
│ ├── .npmignore
│ ├── bin
│ │ └── createWidget.mjs
│ ├── LICENSE
│ └── package.json
├── integration-custom-element
│ ├── cli
│ │ └── cssBundle.mjs
│ ├── .npmrc
│ ├── babel.config.js
│ ├── .npmignore
│ ├── jest.config.js
│ ├── rollup.config.mjs
│ └── LICENSE
├── cli
│ ├── .npmrc
│ ├── .npmignore
│ ├── jest.config.js
│ ├── src
│ │ ├── index.mjs
│ │ ├── devClient
│ │ │ ├── reload.mjs
│ │ │ ├── index.mjs
│ │ │ └── WebSocketClient.mjs
│ │ ├── commands
│ │ │ ├── constant.mjs
│ │ │ ├── start.mjs
│ │ │ ├── build.mjs
│ │ │ ├── dev.mjs
│ │ │ ├── test.mjs
│ │ │ ├── userDefined.mjs
│ │ │ └── custom.mjs
│ │ ├── templates
│ │ │ ├── body.ejs
│ │ │ ├── playground.ejs
│ │ │ ├── footer.ejs
│ │ │ └── head.ejs
│ │ ├── emitter.mjs
│ │ ├── clearBuildFolder.mjs
│ │ ├── context.mjs
│ │ ├── commandConfig.mjs
│ │ ├── plugins
│ │ │ ├── excludeVendorsFromSourceMapPlugin.mjs
│ │ │ └── aliasPlugin.mjs
│ │ ├── taskConfig.mjs
│ │ ├── handleExit.mjs
│ │ ├── runBuild.mjs
│ │ ├── runTask.mjs
│ │ ├── websocket.mjs
│ │ ├── widgetServer.mjs
│ │ ├── server.mjs
│ │ ├── CLIConfig.mjs
│ │ └── utils.mjs
│ └── LICENSE
├── core
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── tsconfig.json
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── src
│ │ ├── index.js
│ │ └── __tests__
│ │ │ └── indexSpec.js
│ ├── LICENSE
│ └── package.json
├── preact
│ ├── src
│ │ ├── client.ts
│ │ └── server.ts
│ ├── .npmignore
│ ├── entries
│ │ ├── client.js
│ │ └── server.js
│ ├── tsconfig.json
│ ├── rollup.config.mjs
│ ├── cli
│ │ └── index.mjs
│ └── package.json
├── svelte
│ ├── src
│ │ ├── client.ts
│ │ ├── server.ts
│ │ └── types.ts
│ ├── .npmignore
│ ├── entries
│ │ ├── client.js
│ │ └── server.js
│ ├── tsconfig.json
│ ├── rollup.config.mjs
│ ├── cli
│ │ └── index.mjs
│ └── package.json
├── uhtml
│ ├── src
│ │ ├── client.ts
│ │ ├── server.ts
│ │ └── modules.d.ts
│ ├── .npmignore
│ ├── entries
│ │ ├── client.js
│ │ └── server.js
│ ├── tsconfig.json
│ ├── rollup.config.mjs
│ ├── cli
│ │ └── index.mjs
│ ├── webpack
│ │ └── index.js
│ └── package.json
├── integration
│ ├── .npmrc
│ ├── babel.config.js
│ ├── .npmignore
│ ├── jest.config.js
│ ├── rollup.config.mjs
│ └── LICENSE
├── plugin-error
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── src
│ │ ├── GenericError.js
│ │ └── __tests__
│ │ │ └── GenericErrorSpec.js
│ ├── LICENSE
│ ├── server
│ │ └── index.js
│ └── README.md
├── integration-react
│ ├── .npmrc
│ ├── babel.config.js
│ ├── src
│ │ ├── index.js
│ │ └── __tests__
│ │ │ ├── __snapshots__
│ │ │ └── WidgetWrapperSpec.jsx.snap
│ │ │ └── indexSpec.jsx
│ ├── jest.setup.js
│ ├── .npmignore
│ ├── jest.config.js
│ ├── LICENSE
│ └── rollup.config.mjs
├── plugin-component
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── tsconfig.json
│ ├── rollup.config.mjs
│ ├── helpers.d.ts
│ ├── LICENSE
│ ├── README.md
│ └── src
│ │ └── helpers.js
├── plugin-http-cache
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── LICENSE
│ └── src
│ │ └── CacheEntry.js
├── plugin-router
│ ├── .npmrc
│ ├── babel.config.js
│ ├── src
│ │ └── RouterEvents.js
│ ├── .npmignore
│ ├── jest.config.js
│ ├── rollup.config.mjs
│ └── LICENSE
├── tool-storybook
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── rollup.config.mjs
│ ├── .npmignore
│ ├── LICENSE
│ ├── src
│ │ └── index.js
│ ├── README.md
│ └── package.json
├── plugin-css-scrambler
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── server
│ │ └── index.js
│ ├── src
│ │ ├── index.js
│ │ ├── numberToCssClass.js
│ │ ├── __tests__
│ │ │ └── indexSpec.js
│ │ └── scramblerFactory.js
│ └── LICENSE
├── plugin-event-emitter
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── LICENSE
│ ├── README.md
│ ├── src
│ │ └── index.js
│ └── package.json
├── plugin-graphql-client
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── src
│ │ └── error
│ │ │ ├── GraphQLError.js
│ │ │ └── UnauthorizedError.js
│ ├── .npmignore
│ ├── webpack.js
│ ├── rollup.config.mjs
│ └── LICENSE
├── plugin-http-client
│ ├── .npmrc
│ ├── src
│ │ └── __mocks__
│ │ │ └── node-fetch.js
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── LICENSE
│ ├── README.md
│ └── package.json
├── plugin-select-preact
│ ├── .npmrc
│ ├── .npmignore
│ ├── jest.config.js
│ ├── src
│ │ ├── SelectProvider.jsx
│ │ └── index.js
│ ├── tsconfig.json
│ ├── rollup.config.mjs
│ ├── babel.config.js
│ ├── LICENSE
│ ├── types.d.ts
│ └── CHANGELOG.md
├── plugin-session-storage
│ ├── .npmrc
│ ├── babel.config.js
│ ├── jest.config.js
│ ├── .npmignore
│ ├── rollup.config.mjs
│ ├── LICENSE
│ └── package.json
├── tools
│ ├── index.js
│ ├── babel.config.js
│ ├── bin
│ │ └── merkurTools.js
│ ├── liveReloadServer.cjs
│ ├── command
│ │ └── livereload.js
│ ├── LICENSE
│ ├── jest.config.js
│ ├── websocket.cjs
│ └── package.json
└── tool-webpack
│ ├── module
│ └── bundleAnalyzer.cjs
│ ├── webpack
│ └── cache.cjs
│ └── LICENSE
├── .npmrc
├── .gitattributes
├── commitlint.config.js
├── images
├── hello-widget.png
├── merkur-logo.png
├── merkur-illustration.png
└── merkur-integration-lifecycle.png
├── .gitignore
├── .prettierignore
├── utils
├── verdaccioConfig.yml
├── extractChangelog.js
├── copyReadme.js
└── restoreLatestTag.mjs
├── lerna.json
├── jest.config.js
├── tsconfig.json
└── LICENSE
/.nvmrc:
--------------------------------------------------------------------------------
1 | 24
2 |
--------------------------------------------------------------------------------
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | merkur.js.org
2 |
--------------------------------------------------------------------------------
/website/static/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/create-widget/template/.nvmrc:
--------------------------------------------------------------------------------
1 | 20
2 |
--------------------------------------------------------------------------------
/packages/create-widget/template/jest.setup.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | npx --no-install lint-staged
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/integration-custom-element/cli/cssBundle.mjs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/config/test.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | npx --no-install commitlint --edit "$1"
2 |
--------------------------------------------------------------------------------
/packages/cli/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/core/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/preact/src/client.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/client';
2 |
--------------------------------------------------------------------------------
/packages/preact/src/server.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/server';
2 |
--------------------------------------------------------------------------------
/packages/svelte/src/client.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/client';
2 |
--------------------------------------------------------------------------------
/packages/svelte/src/server.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/server';
2 |
--------------------------------------------------------------------------------
/packages/uhtml/src/client.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/client';
2 |
--------------------------------------------------------------------------------
/packages/uhtml/src/server.ts:
--------------------------------------------------------------------------------
1 | export * from './factory/server';
2 |
--------------------------------------------------------------------------------
/packages/integration/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-error/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | package-lock.json binary
2 | packages/*/package-lock.json binary
--------------------------------------------------------------------------------
/packages/create-widget/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/integration-react/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-component/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-http-cache/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-router/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/tool-storybook/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/packages/integration-custom-element/.npmrc:
--------------------------------------------------------------------------------
1 | registry = "https://registry.npmjs.org/"
2 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = { extends: ['@commitlint/config-conventional'] };
2 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/src/__mocks__/node-fetch.js:
--------------------------------------------------------------------------------
1 | module.exports = function () {};
2 |
--------------------------------------------------------------------------------
/packages/uhtml/src/modules.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'uhtml';
2 | declare module 'ucontent';
3 |
--------------------------------------------------------------------------------
/images/hello-widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/images/hello-widget.png
--------------------------------------------------------------------------------
/images/merkur-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/images/merkur-logo.png
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/jest.setup.js:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom';
2 |
--------------------------------------------------------------------------------
/packages/tools/index.js:
--------------------------------------------------------------------------------
1 | console.log('require configs directly'); // eslint-disable-line no-console
2 |
--------------------------------------------------------------------------------
/website/static/img/slots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/slots.png
--------------------------------------------------------------------------------
/images/merkur-illustration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/images/merkur-illustration.png
--------------------------------------------------------------------------------
/packages/uhtml/.npmignore:
--------------------------------------------------------------------------------
1 | *
2 | !cli/**/*
3 | !lib/**/*
4 | !entries/**/*
5 | !webpack/**/*
6 | !package.json
7 |
--------------------------------------------------------------------------------
/website/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/favicon.ico
--------------------------------------------------------------------------------
/packages/cli/.npmignore:
--------------------------------------------------------------------------------
1 | *
2 | !cli/**/*
3 | !lib/**/*
4 | !bin/**/*
5 | !src/**/*
6 | !package.json
7 | !types.d.ts
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {},
3 | "devDependencies": {}
4 | }
5 |
--------------------------------------------------------------------------------
/packages/preact/.npmignore:
--------------------------------------------------------------------------------
1 | *
2 | !cli/**/*
3 | !lib/**/*
4 | !entries/**/*
5 | !webpack/**/*
6 | !package.json
7 |
--------------------------------------------------------------------------------
/packages/svelte/.npmignore:
--------------------------------------------------------------------------------
1 | *
2 | !cli/**/*
3 | !lib/**/*
4 | !entries/**/*
5 | !webpack/**/*
6 | !package.json
7 |
--------------------------------------------------------------------------------
/packages/core/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/website/static/img/hello-widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/hello-widget.png
--------------------------------------------------------------------------------
/website/static/img/merkur-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/merkur-logo.png
--------------------------------------------------------------------------------
/packages/integration/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-error/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/website/static/img/merkur-concept.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/merkur-concept.jpg
--------------------------------------------------------------------------------
/images/merkur-integration-lifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/images/merkur-integration-lifecycle.png
--------------------------------------------------------------------------------
/packages/create-widget/template/server/routes/error/index.js:
--------------------------------------------------------------------------------
1 | const error = require('./error');
2 |
3 | module.exports = error;
4 |
--------------------------------------------------------------------------------
/packages/plugin-component/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-http-cache/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-router/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/tool-storybook/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/cli/jest.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | testEnvironment: 'node',
3 | testMatch: ['**/__tests__/**/*Spec.mjs'],
4 | };
5 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/plugin-router/src/RouterEvents.js:
--------------------------------------------------------------------------------
1 | export default Object.freeze({
2 | REDIRECT: '@merkur/plugin-router.redirect',
3 | });
4 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/website/static/img/merkur-illustration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/merkur-illustration.png
--------------------------------------------------------------------------------
/packages/integration-custom-element/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/core/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...defaultConfig,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/routes/widgetAPI/index.js:
--------------------------------------------------------------------------------
1 | const widgetAPI = require('./widgetAPI');
2 |
3 | module.exports = widgetAPI;
4 |
--------------------------------------------------------------------------------
/packages/plugin-component/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/plugin-http-cache/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/tool-storybook/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/website/static/img/merkur-integration-info.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/merkur-integration-info.jpg
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = { ...defaultConfig };
4 |
--------------------------------------------------------------------------------
/packages/create-widget/template/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const config = require('@merkur/tools/eslint.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@merkur/svelte": "0.44.0"
4 | },
5 | "devDependencies": {}
6 | }
7 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@merkur/uhtml": "0.44.0"
4 | },
5 | "devDependencies": {}
6 | }
7 |
--------------------------------------------------------------------------------
/website/static/img/merkur-integration-lifecycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mjancarik/merkur/HEAD/website/static/img/merkur-integration-lifecycle.png
--------------------------------------------------------------------------------
/packages/create-widget/template/.prettierignore:
--------------------------------------------------------------------------------
1 | /docs
2 | /doc
3 | /node_modules
4 | /node_modules/*
5 | /dist
6 | /lib
7 | /build
8 | /server/static
9 | /coverage
--------------------------------------------------------------------------------
/packages/create-widget/template/merkur.config.mjs:
--------------------------------------------------------------------------------
1 | /**
2 | * @type import('@merkur/cli').defineConfig
3 | */
4 | export default function () {
5 | return {};
6 | }
7 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/config/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "environment": "development",
3 | "widget": {
4 | "apiUrl": "https://api.github.dev/"
5 | }
6 | }
--------------------------------------------------------------------------------
/packages/create-widget/template/server/config/production.json:
--------------------------------------------------------------------------------
1 | {
2 | "environment": "production",
3 | "widget": {
4 | "apiUrl": "https://api.github.com/"
5 | }
6 | }
--------------------------------------------------------------------------------
/packages/integration-react/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['@babel/preset-react'],
3 | plugins: ['@babel/plugin-transform-modules-commonjs'],
4 | };
5 |
--------------------------------------------------------------------------------
/packages/integration-react/src/index.js:
--------------------------------------------------------------------------------
1 | import MerkurWidget from './MerkurWidget';
2 | import MerkurSlot from './MerkurSlot';
3 |
4 | export { MerkurWidget, MerkurSlot };
5 |
--------------------------------------------------------------------------------
/packages/cli/src/index.mjs:
--------------------------------------------------------------------------------
1 | import { createLogger } from './logger.mjs';
2 |
3 | import { addServerConfig } from './utils.mjs';
4 |
5 | export { createLogger, addServerConfig };
6 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/src/error/GraphQLError.js:
--------------------------------------------------------------------------------
1 | import { GenericError } from '@merkur/plugin-error';
2 |
3 | export default class GraphQLError extends GenericError {}
4 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/src/error/UnauthorizedError.js:
--------------------------------------------------------------------------------
1 | import GraphQLError from './GraphQLError';
2 |
3 | export default class UnauthorizedError extends GraphQLError {}
4 |
--------------------------------------------------------------------------------
/packages/cli/src/devClient/reload.mjs:
--------------------------------------------------------------------------------
1 | export async function reload({ to, command }) {
2 | if (to === 'browser' && command === 'reload') {
3 | location.reload();
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/components/WidgetContext.js:
--------------------------------------------------------------------------------
1 | import { createContext } from 'preact';
2 |
3 | const WidgetContext = createContext();
4 |
5 | export default WidgetContext;
6 |
--------------------------------------------------------------------------------
/packages/uhtml/entries/client.js:
--------------------------------------------------------------------------------
1 | import { createUHtmlWidget } from '@merkur/uhtml/client';
2 |
3 | import widgetProperties from '@widget';
4 |
5 | createUHtmlWidget({
6 | ...widgetProperties,
7 | });
8 |
--------------------------------------------------------------------------------
/packages/integration-react/src/__tests__/__snapshots__/WidgetWrapperSpec.jsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`SelectorIdentifierMap should match snapshot 1`] = `undefined`;
4 |
--------------------------------------------------------------------------------
/packages/preact/entries/client.js:
--------------------------------------------------------------------------------
1 | import { createPreactWidget } from '@merkur/preact/client';
2 |
3 | import widgetProperties from '@widget';
4 |
5 | createPreactWidget({
6 | ...widgetProperties,
7 | });
8 |
--------------------------------------------------------------------------------
/packages/svelte/entries/client.js:
--------------------------------------------------------------------------------
1 | import { createSvelteWidget } from '@merkur/svelte/client';
2 |
3 | import widgetProperties from '@widget';
4 |
5 | createSvelteWidget({
6 | ...widgetProperties,
7 | });
8 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/.eslintrc.js:
--------------------------------------------------------------------------------
1 | let config = require('@merkur/tools/eslint.config.js');
2 |
3 | config.settings.react.pragma = 'h';
4 |
5 | module.exports = {
6 | ...config,
7 | };
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .history/
3 | .vscode/
4 | .DS_Store
5 | .jekyll-cache/
6 | node_modules/
7 | dist/
8 | es/
9 | lib/
10 | coverage/
11 | current-changelog.txt
12 | !packages/create-widget/template/src/lib
13 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/merkur.config.mjs:
--------------------------------------------------------------------------------
1 | /**
2 | * @type import('@merkur/cli').defineConfig
3 | */
4 | export default function () {
5 | return {
6 | extends: ['@merkur/uhtml/cli'],
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/constant.mjs:
--------------------------------------------------------------------------------
1 | export const COMMAND_NAME = {
2 | START: 'start',
3 | DEV: 'dev',
4 | BUILD: 'build',
5 | BUILD_PLAYGROUND: 'build-playground',
6 | TEST: 'test',
7 | CUSTOM: 'custom',
8 | };
9 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/merkur.config.mjs:
--------------------------------------------------------------------------------
1 | /**
2 | * @type import('@merkur/cli').defineConfig
3 | */
4 | export default function () {
5 | return {
6 | extends: ['@merkur/preact/cli'],
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/merkur.config.mjs:
--------------------------------------------------------------------------------
1 | /**
2 | * @type import('@merkur/cli').defineConfig
3 | */
4 | export default function () {
5 | return {
6 | extends: ['@merkur/svelte/cli'],
7 | };
8 | }
9 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/components/WidgetDescription.svelte:
--------------------------------------------------------------------------------
1 |
5 |
6 |
The widget's name is {name}@{version} .
7 |
8 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/components/WidgetDescription.js:
--------------------------------------------------------------------------------
1 | export default function ViewDescription(widget) {
2 | return `The widget's name is ${widget.name}@${widget.version} .
`;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/uhtml/entries/server.js:
--------------------------------------------------------------------------------
1 | import { createUHtmlWidget } from '@merkur/uhtml/server';
2 |
3 | import widgetProperties from '@widget';
4 |
5 | export const createWidget = createUHtmlWidget({
6 | ...widgetProperties,
7 | });
8 |
--------------------------------------------------------------------------------
/packages/create-widget/template/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('@merkur/tools/jest.config.js');
2 |
3 | config.transform = {
4 | '^.+\\.[t|j]sx?$': 'es-jest',
5 | };
6 |
7 | module.exports = {
8 | ...config,
9 | };
10 |
--------------------------------------------------------------------------------
/packages/preact/entries/server.js:
--------------------------------------------------------------------------------
1 | import { createPreactWidget } from '@merkur/preact/server';
2 |
3 | import widgetProperties from '@widget';
4 |
5 | export const createWidget = createPreactWidget({
6 | ...widgetProperties,
7 | });
8 |
--------------------------------------------------------------------------------
/packages/svelte/entries/server.js:
--------------------------------------------------------------------------------
1 | import { createSvelteWidget } from '@merkur/svelte/server';
2 |
3 | import widgetProperties from '@widget';
4 |
5 | export const createWidget = createSvelteWidget({
6 | ...widgetProperties,
7 | });
8 |
--------------------------------------------------------------------------------
/packages/tools/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | [
4 | '@babel/preset-env',
5 | {
6 | targets: {
7 | node: 'current',
8 | },
9 | },
10 | ],
11 | ],
12 | };
13 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | /docs
2 | /doc
3 | /node_modules
4 | /my-widget
5 | /esbuild-widget
6 | /swc-widget
7 | /packages/*/dist
8 | /packages/*/lib
9 | /packages/*/coverage
10 | /packages/*/node_modules
11 | /packages/cli/bin/merkur.mjs
12 | /website
--------------------------------------------------------------------------------
/website/src/components/HomepageFeatures/styles.module.css:
--------------------------------------------------------------------------------
1 | .features {
2 | display: flex;
3 | align-items: center;
4 | padding: 2rem 0;
5 | width: 100%;
6 | }
7 |
8 | .featureSvg {
9 | height: 200px;
10 | width: 200px;
11 | }
12 |
--------------------------------------------------------------------------------
/packages/create-widget/template/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "./",
4 | "paths": {
5 | "#src/*": [
6 | "./src/*"
7 | ],
8 | "@/*": [
9 | "./src/*"
10 | ],
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/packages/svelte/src/types.ts:
--------------------------------------------------------------------------------
1 | import { Widget } from '@merkur/core';
2 | import { WidgetProps, WidgetState } from '@merkur/plugin-component';
3 |
4 | export interface RenderParams {
5 | widget: Widget;
6 | state: WidgetState;
7 | props: WidgetProps;
8 | }
9 |
--------------------------------------------------------------------------------
/website/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // This file is not used in compilation. It is here just for a nice editor experience.
3 | "extends": "@docusaurus/tsconfig",
4 | "compilerOptions": {
5 | "baseUrl": "."
6 | },
7 | "exclude": [".docusaurus", "build"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/components/WidgetDescription.js:
--------------------------------------------------------------------------------
1 | export default function ViewDescription(widget) {
2 | return widget.$dependencies.html`
3 | The widget's name is ${widget.name}@${widget.version} .
4 | `;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/components/Welcome.svelte:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | a tiny extensible javascript library for front-end microservices
7 |
8 |
9 |
--------------------------------------------------------------------------------
/utils/verdaccioConfig.yml:
--------------------------------------------------------------------------------
1 | storage: ./storage
2 | uplinks:
3 | npmjs:
4 | url: https://registry.npmjs.org/
5 | packages:
6 | '**':
7 | access: $all
8 | publish: $all
9 | proxy: npmjs
10 | logs:
11 | - {type: stdout, format: pretty, level: http}
12 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@merkur/preact": "0.44.0"
4 | },
5 | "devDependencies": {
6 | "@testing-library/jest-dom": "^6.5.0",
7 | "@testing-library/preact": "^3.2.4",
8 | "identity-obj-proxy": "^3.0.0"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/integration-react/jest.setup.js:
--------------------------------------------------------------------------------
1 | import Enzyme from 'enzyme';
2 | import Adapter from 'enzyme-adapter-react-16';
3 | import { createSerializer } from 'enzyme-to-json';
4 |
5 | Enzyme.configure({ adapter: new Adapter() });
6 | expect.addSnapshotSerializer(createSerializer({ mode: 'deep' }));
7 |
--------------------------------------------------------------------------------
/packages/plugin-error/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...defaultConfig,
5 | coverageThreshold: {
6 | global: {
7 | functions: 40,
8 | lines: 40,
9 | statements: 40,
10 | },
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/packages/tool-storybook/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | } from '../../createRollupConfig.mjs';
5 |
6 | let esConfig = createRollupESConfig();
7 | let es9Config = createRollupES9Config();
8 |
9 | export default [esConfig, es9Config];
10 |
--------------------------------------------------------------------------------
/packages/core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2020",
6 | "DOM",
7 | "DOM.Iterable"
8 | ],
9 | },
10 | "include": [
11 | "src"
12 | ],
13 | "exclude": [
14 | "**/__tests__/**"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/packages/core/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/integration/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-error/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-router/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/integration-react/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-component/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-http-cache/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/tool-storybook/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/components/WidgetDescription.jsx:
--------------------------------------------------------------------------------
1 | export default function ViewDescription({ name, version }) {
2 | return (
3 |
4 | The widget's name is{' '}
5 |
6 | {name}@{version}
7 |
8 | .
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/views/ErrorView.jsx:
--------------------------------------------------------------------------------
1 | export default function ErrorView({ error }) {
2 | return (
3 |
4 |
Status: {error.status}
5 |
Message: {error.message}
6 |
{error.stack}
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/webpack.js:
--------------------------------------------------------------------------------
1 | function applyGraphqlLoader(config) {
2 | config.module.rules.push({
3 | test: /\.(graphql|gql)$/,
4 | exclude: /node_modules/,
5 | loader: 'graphql-tag/loader',
6 | });
7 |
8 | return config;
9 | }
10 |
11 | module.exports = {
12 | applyGraphqlLoader,
13 | };
14 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/integration-custom-element/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | babel.config.js
16 | jest.config.js
17 | setupJest.js
18 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...defaultConfig,
5 | testEnvironment: 'jsdom',
6 | transform: {
7 | '^.+\\.[jt]sx?$': 'babel-jest',
8 | '^.+\\.mjs$': 'babel-jest',
9 | },
10 | transformIgnorePatterns: [],
11 | };
12 |
--------------------------------------------------------------------------------
/website/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/views/ErrorView.js:
--------------------------------------------------------------------------------
1 | export default function ErrorView(widget) {
2 | return `
3 |
4 |
Status: ${widget.error.status}
5 |
Message: ${widget.error.message}
6 |
${widget.error.stack}
7 |
8 | `;
9 | }
10 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "command": {
3 | "version": {
4 | "message": "chore(release): publish"
5 | },
6 | "publish": {
7 | "conventionalCommits": true,
8 | "preid": "rc",
9 | "verifyAccess": false
10 | }
11 | },
12 | "version": "0.44.1",
13 | "$schema": "node_modules/lerna/schemas/lerna-schema.json"
14 | }
15 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/components/Welcome.jsx:
--------------------------------------------------------------------------------
1 | export default function Welcome() {
2 | return (
3 |
4 |
7 |
a tiny extensible javascript library for front-end microservices
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/packages/integration/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | defaultConfig.testEnvironment = 'jsdom';
4 | defaultConfig.testEnvironmentOptions = {
5 | html: '',
6 | url: 'https://jestjs.io/',
7 | userAgent: 'Agent/007',
8 | };
9 |
10 | module.exports = { ...defaultConfig };
11 |
--------------------------------------------------------------------------------
/packages/plugin-router/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | defaultConfig.testEnvironment = 'jsdom';
4 | defaultConfig.testEnvironmentOptions = {
5 | html: '',
6 | url: 'https://jestjs.io/',
7 | userAgent: 'Agent/007',
8 | };
9 |
10 | module.exports = { ...defaultConfig };
11 |
--------------------------------------------------------------------------------
/packages/create-widget/.npmignore:
--------------------------------------------------------------------------------
1 | /src
2 | /coverage
3 | .babelrc
4 | .eslintrc.js
5 | .gitignore
6 | .npmignore
7 | .npmrc
8 | .prettierignore
9 | .travis.yml
10 | .DS_Store
11 | README.md
12 | CHANGELOG.md
13 | commitlint.config.js
14 | rollup.config.js
15 | jest.config.js
16 | setupJest.js
17 | !/template/*
18 | !/template/**/*
19 | !/views/*
20 | !/views/**/*
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | bail: false,
3 | verbose: true,
4 | testEnvironment: 'node',
5 | prettierPath: null,
6 | coverageThreshold: {
7 | global: {
8 | functions: 50,
9 | lines: 50,
10 | statements: 50,
11 | },
12 | },
13 | modulePaths: ['/'],
14 | testRegex: '(/__tests__/).*Spec\\.jsx?$',
15 | };
16 |
--------------------------------------------------------------------------------
/packages/core/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/views/ErrorView.js:
--------------------------------------------------------------------------------
1 | export default function ErrorView(widget) {
2 | return widget.$dependencies.html`
3 |
4 |
Status: ${widget.error.status}
5 |
Message: ${widget.error.message}
6 |
${widget.error.stack}
7 |
8 | `;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/preact/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2020",
6 | "DOM",
7 | "DOM.Iterable"
8 | ],
9 | "types": [
10 | "plugin-component"
11 | ]
12 | },
13 | "include": [
14 | "src"
15 | ],
16 | "exclude": [
17 | "**/__tests__/**"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/svelte/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2020",
6 | "DOM",
7 | "DOM.Iterable"
8 | ],
9 | "types": [
10 | "plugin-component"
11 | ]
12 | },
13 | "include": [
14 | "src"
15 | ],
16 | "exclude": [
17 | "**/__tests__/**"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/uhtml/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2020",
6 | "DOM",
7 | "DOM.Iterable"
8 | ],
9 | "types": [
10 | "plugin-component"
11 | ]
12 | },
13 | "include": [
14 | "src"
15 | ],
16 | "exclude": [
17 | "**/__tests__/**"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('@merkur/tools/jest.config.js');
2 |
3 | config.setupFilesAfterEnv = ['./jest.setup.js'];
4 | config.transform = {
5 | '^.+\\.[t|j]sx?$': [
6 | 'es-jest',
7 | { jsx: 'automatic', jsxImportSource: 'preact' },
8 | ],
9 | };
10 |
11 | module.exports = {
12 | ...config,
13 | };
14 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/views/ErrorView.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
Status: ${widget.error.status}
9 |
Message: ${widget.error.message}
10 |
${widget.error.stack}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/packages/integration/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/components/Welcome.js:
--------------------------------------------------------------------------------
1 | export default function Welcome() {
2 | return `
3 |
4 |
7 |
8 | a tiny extensible javascript library for front-end microservices
9 |
10 |
11 | `;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/integration-react/src/__tests__/indexSpec.jsx:
--------------------------------------------------------------------------------
1 | import * as module from '../index';
2 |
3 | describe('module @merkur/integration-react', () => {
4 | it('should have interface', () => {
5 | expect(module).toMatchInlineSnapshot(`
6 | {
7 | "MerkurSlot": [Function],
8 | "MerkurWidget": [Function],
9 | }
10 | `);
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/packages/plugin-component/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2018",
6 | "DOM",
7 | "DOM.Iterable"
8 | ],
9 | "types": [
10 | "plugin-component"
11 | ]
12 | },
13 | "include": [
14 | "src"
15 | ],
16 | "exclude": [
17 | "**/__tests__/**"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/plugin-error/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/src/SelectProvider.jsx:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line no-unused-vars
2 | import { h, createContext } from 'preact';
3 |
4 | export const SelectContext = createContext(null);
5 |
6 | export function SelectProvider({ widget, children }) {
7 | return (
8 | {children}
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/packages/cli/src/templates/body.ejs:
--------------------------------------------------------------------------------
1 | <% if(widgetProperties?.slot?.headline?.html){ %>
2 |
3 | <%- widgetProperties?.slot?.headline?.html %>
4 |
5 | <% } %>
6 | <%- html %>
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-http-cache/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "lib": [
5 | "ES2018",
6 | "DOM",
7 | "DOM.Iterable"
8 | ],
9 | "types": [
10 | "plugin-select-preact"
11 | ]
12 | },
13 | "include": [
14 | "src"
15 | ],
16 | "exclude": [
17 | "**/__tests__/**"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/routes/error/error.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 |
3 | const router = express.Router();
4 |
5 | router.use((req, res) => {
6 | res.status(404).json({
7 | error: {
8 | status: 404,
9 | message: `The endpoint ${req.path} doesn't exist.`,
10 | },
11 | });
12 | });
13 |
14 | module.exports = () => ({ router });
15 |
--------------------------------------------------------------------------------
/packages/integration-custom-element/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...defaultConfig,
5 | testEnvironment: 'jsdom',
6 | testEnvironmentOptions: {
7 | html: '',
8 | url: 'https://jestjs.io/',
9 | userAgent: 'Agent/007',
10 | },
11 | coverageThreshold: {},
12 | };
13 |
--------------------------------------------------------------------------------
/packages/integration-custom-element/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig(1);
8 | let es9Config = createRollupES9Config(1);
9 | let umdConfig = createRollupUMDConfig(1);
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | export default [esConfig, es9Config, umdConfig];
12 |
--------------------------------------------------------------------------------
/packages/cli/src/emitter.mjs:
--------------------------------------------------------------------------------
1 | import { Emitter, RESULT_KEY } from '@esmj/emitter';
2 |
3 | const emitter = new Emitter();
4 |
5 | const EMITTER_EVENTS = {
6 | MERKUR_CONFIG: 'onMerkurConfig',
7 | CLI_CONFIG: 'onCliConfig',
8 | CLI_CONTEXT: 'onCliContext',
9 | TASK_CONFIG: 'onTaskConfig',
10 | TASK_BUILD: 'onTaskBuild',
11 | };
12 |
13 | export { emitter, EMITTER_EVENTS, RESULT_KEY };
14 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/components/Welcome.js:
--------------------------------------------------------------------------------
1 | export default function Welcome(widget) {
2 | return widget.$dependencies.html`
3 |
4 |
7 |
8 | a tiny extensible javascript library for front-end microservices
9 |
10 |
11 | `;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/cli/src/clearBuildFolder.mjs:
--------------------------------------------------------------------------------
1 | import { rm } from 'node:fs/promises';
2 |
3 | export async function clearFolder(folderPath) {
4 | try {
5 | await rm(folderPath, {
6 | recursive: true,
7 | force: true,
8 | });
9 | } catch {} //eslint-disable-line no-empty
10 | }
11 |
12 | export async function clearBuildFolder({ merkurConfig }) {
13 | await clearFolder(merkurConfig.widgetServer.buildFolder);
14 | }
15 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: ['@babel/plugin-transform-modules-commonjs'],
3 | presets: [
4 | [
5 | '@babel/preset-react',
6 | {
7 | runtime: 'automatic',
8 | importSource: 'preact',
9 | },
10 | ],
11 | {
12 | test: /\.mjs$/,
13 | presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
14 | },
15 | ],
16 | };
17 |
--------------------------------------------------------------------------------
/packages/cli/src/context.mjs:
--------------------------------------------------------------------------------
1 | import { emitter, EMITTER_EVENTS, RESULT_KEY } from './emitter.mjs';
2 |
3 | export async function createContext() {
4 | let event = {
5 | context: {
6 | task: {},
7 | memory: {},
8 | process: {},
9 | server: {},
10 | },
11 | [RESULT_KEY]: 'context',
12 | };
13 |
14 | event = await emitter.emit(EMITTER_EVENTS.CONTEXT, event);
15 |
16 | return event.context;
17 | }
18 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/components/Counter.js:
--------------------------------------------------------------------------------
1 | export default function Counter(widget) {
2 | return widget.$dependencies.html`
3 |
4 |
Counter widget:
5 |
Count: ${widget.state.counter}
6 |
7 | increase counter
8 |
9 |
10 | reset counter
11 |
12 |
13 | `;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/plugin-error/src/GenericError.js:
--------------------------------------------------------------------------------
1 | import ExtensibleError from './ExtensibleError';
2 |
3 | export default class GenericError extends ExtensibleError {
4 | constructor(message, params) {
5 | super(message);
6 | const { status = 500, ...otherParams } = params;
7 |
8 | this.name = 'Error';
9 | this.status = status;
10 |
11 | this._params = otherParams;
12 | }
13 |
14 | get params() {
15 | return this._params;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/components/Counter.js:
--------------------------------------------------------------------------------
1 | export default function Counter(widget) {
2 | return `
3 |
4 |
Counter widget:
5 |
Count: ${widget.state.counter}
6 |
7 | increase counter
8 |
9 |
10 | reset counter
11 |
12 |
13 | `;
14 | }
15 |
--------------------------------------------------------------------------------
/packages/tools/bin/merkurTools.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const livereload = require('../command/livereload');
4 |
5 | require('yargs')
6 | .command(
7 | 'livereload',
8 | 'livereload command',
9 | (yargs) => {
10 | return yargs.option('port', {
11 | alias: 'p',
12 | describe: 'define livereload port',
13 | });
14 | },
15 | async (argv) => {
16 | return livereload(argv);
17 | },
18 | )
19 | .help().argv;
20 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/server/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
3 | const DEV = 'development';
4 | const ENV =
5 | typeof process !== 'undefined' && process && process.env
6 | ? process.env.NODE_ENV
7 | : DEV;
8 |
9 | function loadClassnameHashtable(path) {
10 | if (ENV === DEV || !fs.existsSync(path)) {
11 | return null;
12 | }
13 |
14 | return JSON.parse(fs.readFileSync(path, 'utf8'));
15 | }
16 |
17 | module.exports = {
18 | loadClassnameHashtable,
19 | };
20 |
--------------------------------------------------------------------------------
/website/src/pages/index.module.css:
--------------------------------------------------------------------------------
1 | /**
2 | * CSS files with the .module.css suffix will be treated as CSS modules
3 | * and scoped locally.
4 | */
5 |
6 | .heroBanner {
7 | padding: 4rem 0;
8 | text-align: center;
9 | position: relative;
10 | overflow: hidden;
11 | }
12 |
13 | @media screen and (max-width: 996px) {
14 | .heroBanner {
15 | padding: 2rem;
16 | }
17 | }
18 |
19 | .buttons {
20 | display: flex;
21 | align-items: center;
22 | justify-content: center;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/views/View.js:
--------------------------------------------------------------------------------
1 | import Counter from '../components/Counter';
2 | import ErrorView from './ErrorView';
3 |
4 | function View(widget) {
5 | if (widget.error && widget.error.status) {
6 | return ErrorView(widget);
7 | }
8 |
9 | return widget.$dependencies.html`
10 |
11 |
12 | ${Counter(widget)}
13 |
14 |
15 | `;
16 | }
17 |
18 | export default View;
19 |
--------------------------------------------------------------------------------
/utils/extractChangelog.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const VERSION_RE = /#+ \[\d+\.\d+\.\d+\].+/gi;
5 | const CHANGELOG = path.resolve(process.cwd(), 'CHANGELOG.md');
6 |
7 | const changelogContents = fs.readFileSync(CHANGELOG, 'utf-8');
8 | const versionChangelogs = changelogContents.split(VERSION_RE);
9 | versionChangelogs.shift();
10 |
11 | fs.writeFileSync(
12 | path.resolve(process.cwd(), 'current-changelog.txt'),
13 | versionChangelogs?.[0].trim() ?? '',
14 | );
15 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/components/Counter.svelte:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
Counter widget:
11 |
Count: {$state.counter}
12 |
13 | increase counter
14 |
15 |
16 | reset counter
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/packages/preact/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import { createRollupTypescriptConfig } from '../../createRollupConfig.mjs';
2 |
3 | export default [
4 | {
5 | ...createRollupTypescriptConfig({
6 | input: './src/client.ts',
7 | dir: './lib/client',
8 | external: ['@merkur/plugin-component/helpers'],
9 | }),
10 | },
11 | {
12 | ...createRollupTypescriptConfig({
13 | input: './src/server.ts',
14 | dir: './lib/server',
15 | external: ['@merkur/plugin-component/helpers'],
16 | }),
17 | },
18 | ];
19 |
--------------------------------------------------------------------------------
/packages/svelte/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import { createRollupTypescriptConfig } from '../../createRollupConfig.mjs';
2 |
3 | export default [
4 | {
5 | ...createRollupTypescriptConfig({
6 | input: './src/client.ts',
7 | dir: './lib/client',
8 | external: ['@merkur/plugin-component/helpers'],
9 | }),
10 | },
11 | {
12 | ...createRollupTypescriptConfig({
13 | input: './src/server.ts',
14 | dir: './lib/server',
15 | external: ['@merkur/plugin-component/helpers'],
16 | }),
17 | },
18 | ];
19 |
--------------------------------------------------------------------------------
/packages/uhtml/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import { createRollupTypescriptConfig } from '../../createRollupConfig.mjs';
2 |
3 | export default [
4 | {
5 | ...createRollupTypescriptConfig({
6 | input: './src/client.ts',
7 | dir: './lib/client',
8 | external: ['@merkur/plugin-component/helpers'],
9 | }),
10 | },
11 | {
12 | ...createRollupTypescriptConfig({
13 | input: './src/server.ts',
14 | dir: './lib/server',
15 | external: ['@merkur/plugin-component/helpers'],
16 | }),
17 | },
18 | ];
19 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/components/Counter.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from 'preact/hooks';
2 |
3 | import WidgetContext from './WidgetContext';
4 |
5 | export default function Counter({ counter }) {
6 | const widget = useContext(WidgetContext);
7 |
8 | return (
9 |
10 |
Counter widget:
11 |
Count: {counter}
12 |
increase counter
13 |
reset counter
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/packages/cli/src/templates/playground.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | <%- include('./head.ejs', {assets, merkurConfig, devClient, widgetProperties}) %>
8 | MERKUR - widget
9 |
10 |
11 |
12 | <%- include('./body.ejs', {assets, merkurConfig, devClient, widgetProperties}) %>
13 | <%- include('./footer.ejs', {assets, merkurConfig, devClient, widgetProperties}) %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/packages/plugin-error/src/__tests__/GenericErrorSpec.js:
--------------------------------------------------------------------------------
1 | import GenericError from '../GenericError';
2 |
3 | describe('GenericError', () => {
4 | it('should be able to create error instance', () => {
5 | const error = new GenericError('Error', {
6 | status: 500,
7 | reason: 'api_error',
8 | });
9 |
10 | expect(error).toBeInstanceOf(GenericError);
11 | expect(error.status).toBe(500);
12 | expect(error.params).toEqual(
13 | expect.objectContaining({
14 | reason: 'api_error',
15 | }),
16 | );
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/packages/tool-webpack/module/bundleAnalyzer.cjs:
--------------------------------------------------------------------------------
1 | const BundleAnalyzerPlugin =
2 | require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
3 |
4 | function applyBundleAnalyzer(config, { isProduction, plugins }) {
5 | config.plugins.push(new BundleAnalyzerPlugin(plugins.BundleAnalyzerPlugin));
6 |
7 | if (!isProduction) {
8 | config.optimization = {
9 | usedExports: true,
10 | minimize: true,
11 | sideEffects: false,
12 | ...config.optimization,
13 | };
14 | }
15 |
16 | return config;
17 | }
18 |
19 | module.exports = { applyBundleAnalyzer };
20 |
--------------------------------------------------------------------------------
/packages/core/src/index.js:
--------------------------------------------------------------------------------
1 | import { createMerkurWidget, defineWidget } from './createMerkurWidget';
2 | import { createMerkur, removeMerkur, getMerkur } from './merkur';
3 | import {
4 | assignMissingKeys,
5 | setDefaultValueForUndefined,
6 | bindWidgetToFunctions,
7 | hookMethod,
8 | isFunction,
9 | } from './utils';
10 |
11 | export {
12 | assignMissingKeys,
13 | bindWidgetToFunctions,
14 | createMerkurWidget,
15 | createMerkur,
16 | getMerkur,
17 | hookMethod,
18 | isFunction,
19 | removeMerkur,
20 | setDefaultValueForUndefined,
21 | defineWidget,
22 | };
23 |
--------------------------------------------------------------------------------
/packages/cli/src/commandConfig.mjs:
--------------------------------------------------------------------------------
1 | import { createCLIConfig } from './CLIConfig.mjs';
2 | import { createContext } from './context.mjs';
3 | import { createMerkurConfig } from './merkurConfig.mjs';
4 |
5 | export async function createCommandConfig({ args, command }) {
6 | const context = await createContext();
7 | const baseCliConfig = await createCLIConfig({ args, command });
8 |
9 | const { merkurConfig, cliConfig } = await createMerkurConfig({
10 | args,
11 | cliConfig: baseCliConfig,
12 | context,
13 | });
14 |
15 | return { context, merkurConfig, cliConfig };
16 | }
17 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "Node16",
5 | "moduleResolution": "Node16",
6 | "importHelpers": true,
7 | "sourceMap": true,
8 | "declaration": true,
9 | "allowJs": true,
10 | "esModuleInterop": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "strict": true,
13 | "skipLibCheck": true,
14 | "resolveJsonModule": true,
15 | "jsx": "react-jsx",
16 | "typeRoots": [
17 | "./types",
18 | "./node_modules/@types",
19 | "./node_modules/@merkur",
20 | ],
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/packages/core/src/__tests__/indexSpec.js:
--------------------------------------------------------------------------------
1 | import * as merkur from '../index';
2 |
3 | describe('merkur module', () => {
4 | it('should keep module interface', () => {
5 | expect(merkur).toMatchInlineSnapshot(`
6 | {
7 | "assignMissingKeys": [Function],
8 | "bindWidgetToFunctions": [Function],
9 | "createMerkur": [Function],
10 | "createMerkurWidget": [Function],
11 | "defineWidget": [Function],
12 | "getMerkur": [Function],
13 | "hookMethod": [Function],
14 | "isFunction": [Function],
15 | "removeMerkur": [Function],
16 | "setDefaultValueForUndefined": [Function],
17 | }
18 | `);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/src/index.js:
--------------------------------------------------------------------------------
1 | import { hookMethod } from '@merkur/core';
2 | import { WIDGET_UPDATE_EVENT } from './useSelect';
3 |
4 | export function selectPlugin() {
5 | return {
6 | create(widget) {
7 | hookMethod(widget, 'update', (widget, originalFunction, ...args) => {
8 | widget.emit(WIDGET_UPDATE_EVENT);
9 |
10 | return originalFunction(...args);
11 | });
12 |
13 | return widget;
14 | },
15 | setup(widget) {
16 | return widget;
17 | },
18 | };
19 | }
20 |
21 | export { useSelect } from './useSelect';
22 | export { SelectProvider } from './SelectProvider.jsx';
23 |
--------------------------------------------------------------------------------
/packages/tools/liveReloadServer.cjs:
--------------------------------------------------------------------------------
1 | const fp = require('find-free-port');
2 | const WebSocket = require('./websocket.cjs');
3 |
4 | async function createLiveReloadServer() {
5 | if (process.env.NODE_ENV === 'development') {
6 | try {
7 | const [freePort] = await fp(4321);
8 | process.env.MERKUR_PLAYGROUND_LIVERELOAD_PORT = freePort;
9 |
10 | WebSocket.createServer({
11 | port: freePort,
12 | });
13 | } catch (error) {
14 | console.error(error);
15 | throw new Error('Unable to retrieve free port for livereload server.');
16 | }
17 | }
18 | }
19 |
20 | module.exports = { createLiveReloadServer };
21 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/views/View.jsx:
--------------------------------------------------------------------------------
1 | import ErrorView from './ErrorView';
2 | import Counter from '../components/Counter';
3 | import WidgetContext from '../components/WidgetContext';
4 |
5 | function View(widget) {
6 | if (widget.error && widget.error.status) {
7 | return ;
8 | }
9 |
10 | return (
11 |
12 |
17 |
18 | );
19 | }
20 |
21 | export default View;
22 |
--------------------------------------------------------------------------------
/packages/tools/command/livereload.js:
--------------------------------------------------------------------------------
1 | const { createClient } = require('../websocket.cjs');
2 |
3 | function livereload(options) {
4 | new Promise((resolve) => {
5 | options = Object.assign({}, options);
6 |
7 | const client = createClient(options);
8 | client.on('error', () => {
9 | console.info('Livereload is disabled.'); //eslint-disable-line no-console
10 | resolve();
11 | });
12 |
13 | client.on('open', function open() {
14 | client.send(JSON.stringify({ to: 'browser', command: 'reload' }));
15 | client.terminate();
16 | resolve();
17 | });
18 |
19 | return client;
20 | });
21 | }
22 |
23 | module.exports = livereload;
24 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/start.mjs:
--------------------------------------------------------------------------------
1 | import { createCommandConfig } from '../commandConfig.mjs';
2 | import { runDevServer } from '../devServer.mjs';
3 | import { runWidgetServer } from '../widgetServer.mjs';
4 | import { handleExit } from '../handleExit.mjs';
5 |
6 | export async function start({ args, command }) {
7 | const { context, cliConfig, merkurConfig } = await createCommandConfig({
8 | args,
9 | command,
10 | });
11 |
12 | await handleExit({ context });
13 |
14 | cliConfig.hasRunDevServer &&
15 | (await runDevServer({ merkurConfig, cliConfig, context }));
16 | cliConfig.hasRunWidgetServer &&
17 | (await runWidgetServer({ merkurConfig, cliConfig, context }));
18 | }
19 |
--------------------------------------------------------------------------------
/packages/cli/src/plugins/excludeVendorsFromSourceMapPlugin.mjs:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs/promises';
2 |
3 | export function excludeVendorsFromSourceMapPlugin() {
4 | return {
5 | name: 'excludeVendorsFromSourceMapPlugin',
6 | setup(build) {
7 | build.onLoad({ filter: /\/node_modules\/.*\.js?$/ }, async (args) => {
8 | const contents = await fs.readFile(args.path, { encoding: 'utf8' });
9 |
10 | return {
11 | contents:
12 | contents +
13 | '\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==',
14 | loader: 'default',
15 | };
16 | });
17 | },
18 | };
19 | }
20 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/webpack.config.js:
--------------------------------------------------------------------------------
1 | const { applyUHtmlConfig } = require('@merkur/uhtml/webpack');
2 | const {
3 | createLiveReloadServer,
4 | createWebConfig,
5 | createNodeConfig,
6 | applyES9Transformation,
7 | applyStyleLoaders,
8 | pipe,
9 | } = require('@merkur/tool-webpack');
10 |
11 | module.exports = createLiveReloadServer().then(() =>
12 | Promise.all([
13 | pipe(createWebConfig, applyUHtmlConfig, applyStyleLoaders)(),
14 | pipe(
15 | createWebConfig,
16 | applyUHtmlConfig,
17 | applyStyleLoaders,
18 | applyES9Transformation,
19 | )(),
20 | pipe(createNodeConfig, applyUHtmlConfig, applyStyleLoaders)(),
21 | ]),
22 | );
23 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/__integration__/appSpec.js:
--------------------------------------------------------------------------------
1 | import request from 'supertest';
2 |
3 | import { app } from '../app';
4 |
5 | describe('Widget', () => {
6 | it('should return merkur JSON structure for widget', async () => {
7 | const res = await request(app).get('/widget');
8 |
9 | expect(res.statusCode).toEqual(200);
10 | expect(res.body.assets.length).toBeGreaterThan(0);
11 | delete res.body.assets;
12 | expect(res.body).toMatchSnapshot();
13 | });
14 |
15 | it('should return 404 for not defined route', async () => {
16 | const res = await request(app).get('/x');
17 |
18 | expect(res.statusCode).toEqual(404);
19 | expect(res.body.error.status).toEqual(404);
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/integration-react/jest.config.js:
--------------------------------------------------------------------------------
1 | const defaultConfig = require('../../jest.config.js');
2 |
3 | defaultConfig.setupFilesAfterEnv = ['./jest.setup.js'];
4 | defaultConfig.testEnvironment = 'jsdom';
5 | defaultConfig.testEnvironmentOptions = {
6 | html: '',
7 | url: 'https://jestjs.io/',
8 | userAgent: 'Agent/007',
9 | };
10 | defaultConfig.transform = {
11 | '^.+\\.[t|j]sx?$': 'babel-jest',
12 | };
13 | defaultConfig.transformIgnorePatterns = [];
14 | defaultConfig.moduleNameMapper = {
15 | 'cheerio/lib/utils': [
16 | '/node_modules/cheerio/lib/utils.js',
17 | '/../../node_modules/cheerio/lib/utils.js',
18 | ],
19 | };
20 |
21 | module.exports = { ...defaultConfig };
22 |
--------------------------------------------------------------------------------
/utils/copyReadme.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const PACKAGES_DIR = path.resolve(process.cwd(), 'packages');
5 | const README = path.resolve(process.cwd(), 'README.md');
6 |
7 | const PACKAGES = fs.readdirSync(PACKAGES_DIR);
8 | const IGNORED_PACKAGES = [
9 | 'plugin-component',
10 | 'plugin-event-emitter',
11 | 'plugin-http-client',
12 | 'plugin-error',
13 | 'plugin-css-scrambler',
14 | 'tool-storybook',
15 | ];
16 |
17 | PACKAGES.forEach((packageName) => {
18 | if (packageName[0] === '.' || IGNORED_PACKAGES.includes(packageName)) {
19 | return;
20 | }
21 |
22 | let modulePath = path.resolve(PACKAGES_DIR, packageName);
23 |
24 | fs.copyFileSync(README, modulePath + '/README.md');
25 | });
26 |
--------------------------------------------------------------------------------
/packages/plugin-component/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | createRollupUMDConfig,
5 | } from '../../createRollupConfig.mjs';
6 |
7 | let esConfig = createRollupESConfig();
8 | let es9Config = createRollupES9Config();
9 | let umdConfig = createRollupUMDConfig();
10 |
11 | let helpersConfig = createRollupESConfig();
12 | let helpersES9Config = createRollupES9Config();
13 | let umdHelpersConfig = createRollupUMDConfig();
14 | helpersConfig.input = './src/helpers.js';
15 | helpersES9Config.input = './src/helpers.js';
16 | umdHelpersConfig.input = './src/helpers.js';
17 |
18 | export default [
19 | esConfig,
20 | es9Config,
21 | umdConfig,
22 | helpersConfig,
23 | helpersES9Config,
24 | umdHelpersConfig,
25 | ];
26 |
--------------------------------------------------------------------------------
/website/src/pages/demo.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 2rem;
3 | display: flex;
4 | justify-content: center;
5 | }
6 |
7 | .widget {
8 | border: 1px solid #e0e0e0;
9 | padding: 2rem;
10 | border-radius: 8px;
11 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
12 | width: 100%;
13 | max-width: 500px;
14 | }
15 |
16 | .counter {
17 | margin: 1.5rem 0;
18 | font-size: 1.2rem;
19 | }
20 |
21 | .controls {
22 | display: flex;
23 | gap: 1rem;
24 | }
25 |
26 | .controls button {
27 | padding: 0.5rem 1rem;
28 | border: none;
29 | border-radius: 4px;
30 | background-color: #2e8555;
31 | color: white;
32 | cursor: pointer;
33 | transition: background-color 0.3s;
34 | }
35 |
36 | .controls button:hover {
37 | background-color: #25693f;
38 | }
39 |
--------------------------------------------------------------------------------
/packages/cli/src/taskConfig.mjs:
--------------------------------------------------------------------------------
1 | import { EMITTER_EVENTS, emitter, RESULT_KEY } from './emitter.mjs';
2 |
3 | export async function createTaskConfig({
4 | cliConfig,
5 | definition,
6 | context,
7 | } = {}) {
8 | let event = {
9 | config: {
10 | isServer: definition?.build?.platform === 'node',
11 | writeToDisk: definition?.build?.write ?? cliConfig.writeToDisk,
12 | sourcemap: definition?.build?.sourcemap ?? cliConfig.sourcemap,
13 | analyze: definition?.build?.metafile ?? cliConfig.analyze,
14 | ...definition.config,
15 | },
16 | definition,
17 | cliConfig,
18 | context,
19 | [RESULT_KEY]: 'config',
20 | };
21 |
22 | event = await emitter.emit(EMITTER_EVENTS.TASK_CONFIG, event);
23 |
24 | return event.config;
25 | }
26 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/slots/HeadlineSlot.js:
--------------------------------------------------------------------------------
1 | import Welcome from '../components/Welcome';
2 | import WidgetDescription from '../components/WidgetDescription';
3 | import ErrorView from '../views/ErrorView';
4 |
5 | function HeadlineSlot(widget) {
6 | if (widget.error && widget.error.status) {
7 | return ErrorView(widget);
8 | }
9 |
10 | return widget.$dependencies.html`
11 |
12 |
13 |
14 | ${Welcome(widget)}
15 |
Current count: ${widget.state.counter}
16 | ${WidgetDescription(widget)}
17 |
18 |
19 |
20 | `;
21 | }
22 |
23 | export default HeadlineSlot;
24 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/slots/HeadlineSlot.jsx:
--------------------------------------------------------------------------------
1 | import Welcome from '../components/Welcome';
2 | import WidgetContext from '../components/WidgetContext';
3 | import WidgetDescription from '../components/WidgetDescription';
4 |
5 | function HeadlineSlot(widget) {
6 | if (widget.error && widget.error.status) {
7 | return null;
8 | }
9 |
10 | return (
11 |
12 |
13 |
14 |
15 |
Current count: {widget.state.counter}
16 |
17 |
18 |
19 |
20 | );
21 | }
22 |
23 | export default HeadlineSlot;
24 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/entries/server.js:
--------------------------------------------------------------------------------
1 | import { createMerkurWidget } from '@merkur/core';
2 |
3 | import { viewFactory } from '../views/View';
4 | import widgetProperties from '@widget';
5 |
6 | export function createWidget(widgetParams) {
7 | return createMerkurWidget({
8 | ...widgetProperties,
9 | ...widgetParams,
10 | $dependencies: {},
11 | async mount(widget) {
12 | const { View, slot = {} } = await viewFactory(widget);
13 |
14 | return {
15 | html: View(widget),
16 | slot: Object.keys(slot).reduce((acc, cur) => {
17 | acc[cur] = {
18 | name: slot[cur].name,
19 | html: slot[cur].View(widget),
20 | };
21 |
22 | return acc;
23 | }, {}),
24 | };
25 | },
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/packages/plugin-router/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | } from '../../createRollupConfig.mjs';
5 |
6 | let esConfig = createRollupESConfig();
7 | let es9Config = createRollupES9Config();
8 |
9 | let routerEventsConfig = {
10 | input: 'src/RouterEvents.js',
11 | };
12 |
13 | let routerEventsEsConfig = { ...esConfig, ...routerEventsConfig };
14 | let routerEventsEs9Config = { ...es9Config, ...routerEventsConfig };
15 |
16 | let extendedExternal = ['universal-router', 'universal-router/generateUrls'];
17 |
18 | esConfig.external = [...esConfig.external, ...extendedExternal];
19 | es9Config.external = [...es9Config.external, ...extendedExternal];
20 |
21 | export default [
22 | esConfig,
23 | es9Config,
24 | routerEventsEsConfig,
25 | routerEventsEs9Config,
26 | ];
27 |
--------------------------------------------------------------------------------
/packages/plugin-component/helpers.d.ts:
--------------------------------------------------------------------------------
1 | import { Widget } from '@merkur/core';
2 | import {
3 | ViewFactory,
4 | ViewFactorySlotType,
5 | ViewType,
6 | } from '@merkur/plugin-component';
7 | export type MapViewArgs = {
8 | View: ViewType;
9 | ErrorView?: ViewType;
10 | containerSelector: string;
11 | container: Element | null;
12 | isSlot: boolean;
13 | slot?: Record<
14 | string,
15 | {
16 | isSlot: boolean;
17 | containerSelector?: string;
18 | container?: Element;
19 | } & ViewFactorySlotType
20 | >;
21 | };
22 | /**
23 | * Utility function to iterate thorugh views returned from
24 | * view factory and call callback function with view arguments
25 | * on each them.
26 | */
27 | export declare function mapViews(
28 | widget: Widget,
29 | viewFactory: ViewFactory,
30 | callback: (viewArgs: MapViewArgs) => T,
31 | ): Promise;
32 |
--------------------------------------------------------------------------------
/packages/cli/src/plugins/aliasPlugin.mjs:
--------------------------------------------------------------------------------
1 | import { createLogger } from '../logger.mjs';
2 |
3 | import chalk from 'chalk';
4 |
5 | export function aliasPlugin({ definition, cliConfig }) {
6 | const { projectFolder } = cliConfig;
7 | const logger = createLogger('aliasPlugin', cliConfig);
8 | return {
9 | name: 'aliasPlugin',
10 | setup(build) {
11 | logger.debug(`Setup plugin for "${chalk.cyan(definition.name)}" task.`);
12 |
13 | build.onResolve({ filter: /^@\// }, async (args) => {
14 | const result = await build.resolve(args.path.replace(/^@\//, `./`), {
15 | kind: 'import-statement',
16 | resolveDir: `${projectFolder}/src/`,
17 | });
18 |
19 | if (result.errors.length > 0) {
20 | return { errors: result.errors };
21 | }
22 | return { path: result.path };
23 | });
24 | },
25 | };
26 | }
27 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/views/View.js:
--------------------------------------------------------------------------------
1 | import Counter from '../components/Counter';
2 | import { headlineSlotFactory } from '../slots/HeadlineSlot';
3 | import ErrorView from './ErrorView';
4 |
5 | async function viewFactory(widget) {
6 | const slot = (await Promise.all([headlineSlotFactory(widget)])).reduce(
7 | (acc, cur) => {
8 | acc[cur.name] = cur;
9 |
10 | return acc;
11 | },
12 | {},
13 | );
14 |
15 | return {
16 | View,
17 | ErrorView,
18 | slot,
19 | };
20 | }
21 |
22 | function View(widget) {
23 | if (widget.error && widget.error.status) {
24 | return ErrorView(widget);
25 | }
26 |
27 | return `
28 |
29 |
30 | ${Counter(widget)}
31 |
32 |
33 | `;
34 | }
35 |
36 | export { viewFactory };
37 | export default View;
38 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/views/View.svelte:
--------------------------------------------------------------------------------
1 |
24 |
25 | {#if widget.error && widget.error.message }
26 |
27 |
28 |
29 | {:else}
30 |
35 | {/if}
36 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/webpack.config.js:
--------------------------------------------------------------------------------
1 | const {
2 | createLiveReloadServer,
3 | createWebConfig,
4 | createNodeConfig,
5 | applyES9Transformation,
6 | applyStyleLoaders,
7 | pipe,
8 | } = require('@merkur/tool-webpack');
9 | const {
10 | applySvelteConfig,
11 | applySvelteWeb,
12 | applySvelteNode,
13 | } = require('@merkur/svelte/webpack');
14 |
15 | module.exports = createLiveReloadServer().then(() =>
16 | Promise.all([
17 | pipe(
18 | createWebConfig,
19 | applySvelteConfig,
20 | applyStyleLoaders,
21 | applySvelteWeb,
22 | )(),
23 | pipe(
24 | createWebConfig,
25 | applySvelteConfig,
26 | applyStyleLoaders,
27 | applySvelteWeb,
28 | applyES9Transformation,
29 | )(),
30 | pipe(
31 | createNodeConfig,
32 | applySvelteConfig,
33 | applyStyleLoaders,
34 | applySvelteNode,
35 | )(),
36 | ]),
37 | );
38 |
--------------------------------------------------------------------------------
/packages/uhtml/cli/index.mjs:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from 'node:url';
2 |
3 | export default function ({ emitter, EMITTER_EVENTS }) {
4 | emitter.on(
5 | EMITTER_EVENTS.MERKUR_CONFIG,
6 | function defaultEntries({ merkurConfig }) {
7 | merkurConfig.defaultEntries = {
8 | client: [
9 | fileURLToPath(import.meta.resolve('@merkur/uhtml/entries/client.js')),
10 | ],
11 | server: [
12 | fileURLToPath(import.meta.resolve('@merkur/uhtml/entries/server.js')),
13 | ],
14 | };
15 |
16 | return merkurConfig;
17 | },
18 | );
19 |
20 | emitter.on(
21 | EMITTER_EVENTS.TASK_BUILD,
22 | function defaultBuild({ build, config }) {
23 | build = {
24 | ...build,
25 | external: config.isServer
26 | ? [...(build.external ?? []), 'ucontent']
27 | : build.external,
28 | };
29 |
30 | return build;
31 | },
32 | );
33 | }
34 |
--------------------------------------------------------------------------------
/website/README.md:
--------------------------------------------------------------------------------
1 | # Website
2 |
3 | This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
4 |
5 | ## Installation
6 |
7 | ```bash
8 | yarn
9 | ```
10 |
11 | ## Local Development
12 |
13 | ```bash
14 | yarn start
15 | ```
16 |
17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
18 |
19 | ## Build
20 |
21 | ```bash
22 | yarn build
23 | ```
24 |
25 | This command generates static content into the `build` directory and can be served using any static contents hosting service.
26 |
27 | ## Deployment
28 |
29 | Using SSH:
30 |
31 | ```bash
32 | USE_SSH=true yarn deploy
33 | ```
34 |
35 | Not using SSH:
36 |
37 | ```bash
38 | GIT_USER= yarn deploy
39 | ```
40 |
41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
42 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/build.mjs:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 |
3 | import { createCommandConfig } from '../commandConfig.mjs';
4 | import { runTask } from '../runTask.mjs';
5 | import { createLogger } from '../logger.mjs';
6 | import { time } from '../utils.mjs';
7 | import { handleExit } from '../handleExit.mjs';
8 | import { clearBuildFolder } from '../clearBuildFolder.mjs';
9 |
10 | export async function build({ args, command }) {
11 | const buildTime = time();
12 |
13 | const { context, cliConfig, merkurConfig } = await createCommandConfig({
14 | args,
15 | command,
16 | });
17 |
18 | const logger = createLogger(undefined, cliConfig);
19 |
20 | await handleExit({ context });
21 |
22 | await clearBuildFolder({ merkurConfig, cliConfig });
23 |
24 | const task = await runTask({ merkurConfig, cliConfig, context });
25 |
26 | await Promise.all(Object.values(task));
27 |
28 | logger.log(`Build success ${chalk.green(buildTime())} [ms]`);
29 | }
30 |
--------------------------------------------------------------------------------
/packages/tool-webpack/webpack/cache.cjs:
--------------------------------------------------------------------------------
1 | const { createHash } = require('crypto');
2 | const fs = require('fs');
3 | const path = require('path');
4 |
5 | function createCacheKey(...args) {
6 | let hash;
7 |
8 | try {
9 | hash = createHash('sha256');
10 | } catch (err) {
11 | hash = createHash('md5');
12 | }
13 |
14 | return hash
15 | .update(
16 | args
17 | .filter(Boolean)
18 | .map((value) => JSON.stringify(value))
19 | .join(''),
20 | )
21 | .digest('hex');
22 | }
23 |
24 | function createCache({ cwd, cache, environment }) {
25 | return {
26 | type: 'filesystem',
27 | version: createCacheKey(environment, ...(cache?.versionDependencies ?? [])),
28 | buildDependencies: {
29 | defaultWebpack: ['webpack/lib/'],
30 | config: [path.resolve(cwd, 'webpack.config.js')].filter(fs.existsSync),
31 | },
32 | };
33 | }
34 |
35 | module.exports = {
36 | createCacheKey,
37 | createCache,
38 | };
39 |
--------------------------------------------------------------------------------
/packages/create-widget/bin/createWidget.mjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import path from 'path';
4 | import { fileURLToPath } from 'url';
5 |
6 | import { execaSync } from 'execa';
7 | import chalk from 'chalk';
8 | import yargs from 'yargs';
9 | import { hideBin } from 'yargs/helpers';
10 |
11 | const { argv } = yargs(hideBin(process.argv));
12 |
13 | if (argv._.length === 0) {
14 | // eslint-disable-next-line no-console
15 | console.log(`
16 | Please specify your new project directory:
17 | ${chalk.blue('@merkur/create-widget')} ${chalk.green('')}
18 | For example:
19 | ${chalk.blue('@merkur/create-widget')} ${chalk.green('my-widget')}`);
20 |
21 | process.exit(0);
22 | }
23 |
24 | const __filename = fileURLToPath(import.meta.url);
25 | const __dirname = path.dirname(__filename);
26 |
27 | execaSync(
28 | 'node',
29 | [path.resolve(__dirname, '../scripts/create.mjs'), ...process.argv.slice(2)],
30 | {
31 | stdio: 'inherit',
32 | },
33 | );
34 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/src/index.js:
--------------------------------------------------------------------------------
1 | import { hookMethod } from '@merkur/core';
2 | import scramblerFactory from './scramblerFactory';
3 | import numberToCssClass from './numberToCssClass';
4 |
5 | function cssScramblePlugin() {
6 | return {
7 | async setup(widget, widgetDefinition) {
8 | const { classnameHashtable } = widgetDefinition;
9 | widget.$in.classNameScrambler = scramblerFactory(classnameHashtable);
10 |
11 | widget.cn = (...args) => widget.$in.classNameScrambler(...args).className;
12 |
13 | return widget;
14 | },
15 | async create(widget) {
16 | hookMethod(widget, 'info', infoHook);
17 |
18 | return widget;
19 | },
20 | };
21 | }
22 |
23 | async function infoHook(widget, originalInfo, ...rest) {
24 | const result = await originalInfo(...rest);
25 |
26 | return {
27 | classnameHashtable: widget.classnameHashtable,
28 | ...result,
29 | };
30 | }
31 |
32 | export { numberToCssClass, cssScramblePlugin };
33 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/slots/HeadlineSlot.js:
--------------------------------------------------------------------------------
1 | import Welcome from '../components/Welcome';
2 | import WidgetDescription from '../components/WidgetDescription';
3 | import ErrorView from '../views/ErrorView';
4 |
5 | async function headlineSlotFactory() {
6 | return {
7 | name: 'headline',
8 | View: HeadlineSlot,
9 | };
10 | }
11 |
12 | function HeadlineSlot(widget) {
13 | if (widget.error && widget.error.status) {
14 | return ErrorView(widget);
15 | }
16 |
17 | return `
18 |
19 |
20 |
21 | ${Welcome(widget)}
22 |
Current count: ${
23 | widget.state.counter
24 | }
25 | ${WidgetDescription(widget)}
26 |
27 |
28 |
29 | `;
30 | }
31 |
32 | export { headlineSlotFactory };
33 | export default HeadlineSlot;
34 |
--------------------------------------------------------------------------------
/website/sidebars.ts:
--------------------------------------------------------------------------------
1 | import type { SidebarsConfig } from '@docusaurus/plugin-content-docs';
2 |
3 | // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
4 |
5 | /**
6 | * Creating a sidebar enables you to:
7 | - create an ordered group of docs
8 | - render a sidebar for each doc of that group
9 | - provide next/previous navigation
10 |
11 | The sidebars can be generated from the filesystem, or explicitly defined here.
12 |
13 | Create as many sidebars as you want.
14 | */
15 | const sidebars: SidebarsConfig = {
16 | // By default, Docusaurus generates a sidebar from the docs folder structure
17 | docsSidebar: [{ type: 'autogenerated', dirName: '.' }],
18 |
19 | // But you can create a sidebar manually
20 | /*
21 | tutorialSidebar: [
22 | 'intro',
23 | 'hello',
24 | {
25 | type: 'category',
26 | label: 'Tutorial',
27 | items: ['tutorial-basics/create-a-document'],
28 | },
29 | ],
30 | */
31 | };
32 |
33 | export default sidebars;
34 |
--------------------------------------------------------------------------------
/packages/uhtml/webpack/index.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const fs = require('fs');
3 |
4 | function applyUHtmlConfig(config, { cwd, isServer }) {
5 | // Check for existence of widget entry points
6 | if (
7 | config.entry.widget &&
8 | fs.existsSync(path.join(cwd, config.entry.widget))
9 | ) {
10 | return config;
11 | }
12 |
13 | // TODO should probably be moved to root config, when all frameworks are supported (this will be removed with webpack deprecation)
14 | // Set custom aliases to widget entry point
15 | config.resolve = {
16 | ...config.resolve,
17 | alias: {
18 | '@widget': path.join(cwd, './src/widget.js'),
19 | ...config.resolve.alias,
20 | },
21 | };
22 |
23 | // Add default client/server entries if there are no custom ones
24 | config.entry.widget = require.resolve(
25 | `@merkur/uhtml/entries/${isServer ? 'server' : 'client'}.js`,
26 | );
27 |
28 | return config;
29 | }
30 |
31 | module.exports = {
32 | applyUHtmlConfig,
33 | };
34 |
--------------------------------------------------------------------------------
/packages/cli/src/handleExit.mjs:
--------------------------------------------------------------------------------
1 | import process from 'node:process';
2 |
3 | export async function killProcesses({ context }) {
4 | Object.values(context.process).forEach((childProcess) => {
5 | childProcess.kill('SIGTERM');
6 | });
7 |
8 | Object.values(context.task).forEach((task) => {
9 | task.dispose();
10 | });
11 |
12 | await Promise.all(
13 | Object.values(context.server).map((server) => {
14 | return new Promise((resolve) => {
15 | const timer = setTimeout(() => {
16 | resolve();
17 | }, 100);
18 | server.close(() => {
19 | clearTimeout(timer);
20 | resolve();
21 | });
22 | });
23 | }),
24 | );
25 | }
26 |
27 | export async function handleExit({ context }) {
28 | const handleExit = async () => {
29 | await killProcesses({ context });
30 |
31 | process.exit(0);
32 | };
33 |
34 | process.on('SIGINT', handleExit);
35 | process.on('SIGQUIT', handleExit);
36 | process.on('SIGTERM', handleExit);
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/core/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-error/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Anna Frankova frankova@corvidism.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/preact/cli/index.mjs:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from 'node:url';
2 |
3 | export default function ({ emitter, EMITTER_EVENTS }) {
4 | emitter.on(
5 | EMITTER_EVENTS.MERKUR_CONFIG,
6 | function defaultEntries({ merkurConfig }) {
7 | merkurConfig.defaultEntries = {
8 | client: [
9 | //`${cliConfig.projectFolder}/node_modules/@merkur/preact/entries/client.js`,
10 | fileURLToPath(
11 | import.meta.resolve('@merkur/preact/entries/client.js'),
12 | ),
13 | ],
14 | server: [
15 | //`${cliConfig.projectFolder}/node_modules/@merkur/preact/entries/server.js`,
16 | fileURLToPath(
17 | import.meta.resolve('@merkur/preact/entries/server.js'),
18 | ),
19 | ],
20 | };
21 |
22 | return merkurConfig;
23 | },
24 | );
25 |
26 | emitter.on(EMITTER_EVENTS.TASK_BUILD, function defaultBuild({ build }) {
27 | build = {
28 | ...build,
29 | jsxImportSource: 'preact',
30 | jsx: 'automatic',
31 | };
32 |
33 | return build;
34 | });
35 | }
36 |
--------------------------------------------------------------------------------
/packages/cli/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2024 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 | git s
--------------------------------------------------------------------------------
/packages/plugin-http-cache/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Vojtěch Šimko SimkoVojta@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/tools/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/create-widget/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/create-widget/template/src/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
5 | }
6 |
7 | button {
8 | padding: 12px;
9 | background-color: #d19a66;
10 | border-radius: 6px;
11 | }
12 |
13 | .merkur__icon {
14 | width: 125px;
15 | margin: 0 auto;
16 | }
17 |
18 | .merkur-headline {
19 | background-color: #282c34;
20 | padding: 120px 10px 80px 10px;
21 | color: #a2a8b6;
22 | text-align: center;
23 | }
24 |
25 | .merkur-headline a {
26 | color: white;
27 | text-decoration: none;
28 | }
29 |
30 | .merkur-headline h1 {
31 | font-size: 60px;
32 | margin: 0 0 20px 0;
33 | }
34 |
35 | .merkur-headline h2 {
36 | margin: 0;
37 | line-height: 1.3;
38 | }
39 |
40 | .merkur-headline h3 {
41 | margin: 40px 0 16px 0;
42 | line-height: 1.3;
43 | }
44 |
45 | .merkur__view {
46 | max-width: 1024px;
47 | margin: 0 auto;
48 | }
49 |
50 | .merkur__icon img {
51 | max-width: 100%;
52 | }
53 |
54 | .merkur__error {
55 | padding: 24px;
56 | background-color: #ed858f;
57 | height:100%;
58 | }
59 |
--------------------------------------------------------------------------------
/packages/integration/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2021 Vojtech Simko SimkoVojta@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/src/numberToCssClass.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const CLASSNAME_CHARS = (
4 | 'abcdefghijklmnopqrstuvwxyz' +
5 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
6 | '-'
7 | ).split('');
8 | const EXTENDED_CLASSNAME_CHARS = (
9 | CLASSNAME_CHARS.join('') + '0123456789'
10 | ).split('');
11 |
12 | export default function numberToCssClass(number) {
13 | if (number < CLASSNAME_CHARS.length) {
14 | return CLASSNAME_CHARS[number];
15 | }
16 |
17 | // we have to "shift" the number to adjust for the gap between base53 and
18 | // base64 encoding
19 | number += EXTENDED_CLASSNAME_CHARS.length - CLASSNAME_CHARS.length;
20 |
21 | let className = '';
22 | while (number >= CLASSNAME_CHARS.length) {
23 | className =
24 | EXTENDED_CLASSNAME_CHARS[number % EXTENDED_CLASSNAME_CHARS.length] +
25 | className;
26 | number = Math.floor(number / EXTENDED_CLASSNAME_CHARS.length);
27 | }
28 |
29 | if (number) {
30 | className = CLASSNAME_CHARS[number - 1] + className;
31 | } else {
32 | className = '_' + className;
33 | }
34 |
35 | return className;
36 | }
37 |
--------------------------------------------------------------------------------
/packages/plugin-graphql-client/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2021 Vojtěch Šimko SimkoVojta@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-router/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/tool-storybook/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2021 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/tool-webpack/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/integration-react/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-component/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2023 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/dev.mjs:
--------------------------------------------------------------------------------
1 | import { createCommandConfig } from '../commandConfig.mjs';
2 | import { runDevServer } from '../devServer.mjs';
3 | import { runTask } from '../runTask.mjs';
4 | import { runSocketServer } from '../websocket.mjs';
5 | import { runWidgetServer } from '../widgetServer.mjs';
6 | import { handleExit } from '../handleExit.mjs';
7 | import { clearBuildFolder } from '../clearBuildFolder.mjs';
8 |
9 | export async function dev({ args, command }) {
10 | const { context, cliConfig, merkurConfig } = await createCommandConfig({
11 | args,
12 | command,
13 | });
14 |
15 | await handleExit({ context });
16 |
17 | await clearBuildFolder({ merkurConfig, cliConfig });
18 |
19 | const task = await runTask({ merkurConfig, cliConfig, context });
20 |
21 | await Promise.all(Object.values(task));
22 |
23 | cliConfig.hasRunDevServer &&
24 | (await runDevServer({ merkurConfig, cliConfig, context }));
25 | await runSocketServer({ merkurConfig, cliConfig, context });
26 | cliConfig.hasRunWidgetServer &&
27 | (await runWidgetServer({ merkurConfig, cliConfig, context }));
28 | }
29 |
--------------------------------------------------------------------------------
/packages/integration-custom-element/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2020 Miroslav Jancarik jancarikmiroslav@gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/packages/integration-react/rollup.config.mjs:
--------------------------------------------------------------------------------
1 | import {
2 | createRollupESConfig,
3 | createRollupES9Config,
4 | } from '../../createRollupConfig.mjs';
5 | import resolve from '@rollup/plugin-node-resolve';
6 | import babel from '@rollup/plugin-babel';
7 | import replace from '@rollup/plugin-replace';
8 | import commonjs from '@rollup/plugin-commonjs';
9 |
10 | let esConfig = createRollupESConfig();
11 | let es9Config = createRollupES9Config();
12 |
13 | let extendedPlugins = [
14 | commonjs({
15 | include: /node_modules/,
16 | requireReturnsDefault: 'auto', // <---- this solves default issue
17 | }),
18 | replace({
19 | preventAssignment: false,
20 | values: {
21 | 'process.env.NODE_ENV': JSON.stringify('production'),
22 | },
23 | }),
24 | resolve({
25 | extensions: ['.mjs', '.js', '.jsx', '.json'],
26 | }),
27 | babel({
28 | configFile: false,
29 | babelHelpers: 'inline',
30 | presets: ['@babel/preset-react'],
31 | }),
32 | ];
33 |
34 | esConfig.plugins.push(...extendedPlugins);
35 | es9Config.plugins.push(...extendedPlugins);
36 |
37 | export default [esConfig, es9Config];
38 |
--------------------------------------------------------------------------------
/packages/create-widget/template/src/widget.js:
--------------------------------------------------------------------------------
1 | import { defineWidget } from '@merkur/core';
2 | import { componentPlugin } from '@merkur/plugin-component';
3 | import { errorPlugin } from '@merkur/plugin-error';
4 | import { eventEmitterPlugin } from '@merkur/plugin-event-emitter';
5 |
6 | import { name, version } from '../package.json';
7 | import './style.css';
8 |
9 | export default defineWidget({
10 | name,
11 | version,
12 | $plugins: [componentPlugin, eventEmitterPlugin, errorPlugin],
13 | assets: [
14 | {
15 | name: 'widget.js',
16 | type: 'script',
17 | },
18 | {
19 | name: 'widget.css',
20 | type: 'stylesheet',
21 | },
22 | ],
23 | onClick(widget) {
24 | widget.setState({ counter: widget.state.counter + 1 });
25 | },
26 | onReset(widget) {
27 | widget.setState({ counter: 0 });
28 | },
29 | load(widget) {
30 | // We don't want to set environment into app state
31 | // eslint-disable-next-line no-unused-vars
32 | const { environment, ...restProps } = widget.props;
33 |
34 | return {
35 | counter: 0,
36 | ...restProps,
37 | };
38 | },
39 | });
40 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/types.d.ts:
--------------------------------------------------------------------------------
1 | import { WidgetState } from '@merkur/plugin-component';
2 | type Selector<
3 | D = null,
4 | R extends Record = Record,
5 | > = (state: WidgetState, data: D) => R;
6 | type Intersection<
7 | T extends {
8 | [K in keyof T]: T[K];
9 | },
10 | > = T extends [infer Head, ...infer Tail] ? Head & Intersection : unknown;
11 | export declare function useSelect<
12 | D,
13 | R extends Record[],
14 | S extends {
15 | [I in keyof R]: Selector;
16 | },
17 | >(
18 | widget: any,
19 | data: D,
20 | ...selectors: S
21 | ): [
22 | Intersection<{
23 | [K in keyof S]: ReturnType;
24 | }>,
25 | ];
26 | export declare function createStateSelector<
27 | D,
28 | R extends Record[],
29 | S extends {
30 | [I in keyof R]: Selector;
31 | },
32 | >(
33 | ...selectors: S
34 | ): ((state: WidgetState, data: any) => any) &
35 | import('reselect').OutputSelectorFields<
36 | (args_0: any) => any,
37 | {
38 | clearCache: () => void;
39 | }
40 | > & {
41 | clearCache: () => void;
42 | };
43 |
--------------------------------------------------------------------------------
/packages/cli/src/runBuild.mjs:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs/promises';
2 |
3 | import esbuild from 'esbuild';
4 | import { createLogger } from './logger.mjs';
5 |
6 | export async function runBuild({ cliConfig, build, config }) {
7 | const logger = createLogger(undefined, cliConfig);
8 | const { watch } = cliConfig;
9 |
10 | //es6 === es2015, es9 === es2018, es11 === es2020, es13 ===es2022, es15 === es2024
11 | try {
12 | const result = await (watch
13 | ? esbuild.context(build)
14 | : esbuild.build(build));
15 |
16 | if (config.analyze && result.metafile) {
17 | logger.log(
18 | await esbuild.analyzeMetafile(result.metafile, {
19 | verbose: cliConfig.verbose,
20 | }),
21 | );
22 |
23 | if (build.outdir) {
24 | await fs.writeFile(
25 | `${build.outdir}/${build.entryNames ?? config.name}.meta.json`,
26 | JSON.stringify(result.metafile),
27 | );
28 | }
29 | }
30 |
31 | if (watch) {
32 | await result.watch();
33 | }
34 |
35 | return result;
36 | } catch (error) {
37 | console.error(error);
38 | process.exit(1);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/cli/src/templates/footer.ejs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/server.js:
--------------------------------------------------------------------------------
1 | const cluster = require('cluster');
2 | const os = require('os');
3 |
4 | const { resolveConfig } = require('@merkur/cli/server');
5 | const { merkurConfig } = resolveConfig();
6 |
7 | const { app } = require('./app');
8 |
9 | const { widgetServer } = merkurConfig;
10 |
11 | process.on('uncaughtException', (error) => {
12 | console.error(error);
13 | });
14 |
15 | process.on('unhandledRejection', (error) => {
16 | console.error(error);
17 | });
18 |
19 | if (!widgetServer.clusters || !cluster.isMaster) {
20 | const server = app.listen({ port: widgetServer.port });
21 |
22 | const handleExit = () => {
23 | server.close(() => {
24 | process.exit(0);
25 | });
26 | };
27 |
28 | process.on('SIGINT', handleExit);
29 | process.on('SIGQUIT', handleExit);
30 | process.on('SIGTERM', handleExit);
31 | } else {
32 | let cpuCount = widgetServer.clusters || os.cpus().length;
33 |
34 | for (let i = 0; i < cpuCount; i += 1) {
35 | cluster.fork();
36 | }
37 |
38 | cluster.on('exit', (worker) => {
39 | console.warn(`Worker ${worker.id} died :(`);
40 | cluster.fork();
41 | });
42 | }
43 |
--------------------------------------------------------------------------------
/website/src/css/custom.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Any CSS included here will be global. The classic template
3 | * bundles Infima by default. Infima is a CSS framework designed to
4 | * work well for content-centric websites.
5 | */
6 |
7 | /* You can override the default Infima variables here. */
8 | :root {
9 | --ifm-color-primary: #303846;
10 | --ifm-color-primary-dark: #29784c;
11 | --ifm-color-primary-darker: #277148;
12 | --ifm-color-primary-darkest: #205d3b;
13 | --ifm-color-primary-light: #33925d;
14 | --ifm-color-primary-lighter: #359962;
15 | --ifm-color-primary-lightest: #3cad6e;
16 | --ifm-code-font-size: 95%;
17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
18 | }
19 |
20 | /* For readability concerns, you should choose a lighter palette in dark mode. */
21 | [data-theme='dark'] {
22 | --ifm-color-primary: gray;
23 | --ifm-color-primary-dark: #21af90;
24 | --ifm-color-primary-darker: #1fa588;
25 | --ifm-color-primary-darkest: #1a8870;
26 | --ifm-color-primary-light: #29d5b0;
27 | --ifm-color-primary-lighter: #32d8b4;
28 | --ifm-color-primary-lightest: #4fddbf;
29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
30 | }
31 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/slots/HeadlineSlot.svelte:
--------------------------------------------------------------------------------
1 |
25 |
26 | {#if widget.error && widget.error.message }
27 |
28 |
29 |
30 | {:else}
31 |
32 |
33 |
34 |
35 |
Current count: {state.counter}
36 |
37 |
38 |
39 |
40 | {/if}
41 |
--------------------------------------------------------------------------------
/packages/cli/src/runTask.mjs:
--------------------------------------------------------------------------------
1 | import { createBuildConfig } from './buildConfig.mjs';
2 | import { createTaskConfig } from './taskConfig.mjs';
3 | import { runBuild } from './runBuild.mjs';
4 |
5 | export async function runTask({ cliConfig, merkurConfig, context }) {
6 | const { runTasks } = cliConfig;
7 | let task = { ...merkurConfig.task };
8 |
9 | if (runTasks.length !== 0) {
10 | Object.keys(task)
11 | .filter((taskName) => !runTasks.includes(taskName))
12 | .forEach((taskKey) => {
13 | delete task[taskKey];
14 | });
15 | }
16 |
17 | return Object.keys(task).reduce(async (result, key) => {
18 | const definition = task[key];
19 |
20 | const config = await createTaskConfig({
21 | definition,
22 | merkurConfig,
23 | cliConfig,
24 | context,
25 | });
26 | const build = await createBuildConfig({
27 | definition,
28 | config,
29 | merkurConfig,
30 | cliConfig,
31 | context,
32 | });
33 | result[definition.name] = await runBuild({
34 | definition,
35 | build,
36 | merkurConfig,
37 | cliConfig,
38 | config,
39 | context,
40 | });
41 |
42 | return result;
43 | }, context.task);
44 | }
45 |
--------------------------------------------------------------------------------
/packages/create-widget/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/create-widget",
3 | "version": "0.44.1",
4 | "description": "CLI for creating merkur widget easily.",
5 | "bin": {
6 | "merkur-create-widget": "./bin/createWidget.mjs"
7 | },
8 | "scripts": {
9 | "test": "echo 'Tests pass.'",
10 | "test:es:version": "echo 'Tests pass.'",
11 | "build": "echo 'Build pass.'",
12 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
13 | },
14 | "keywords": [
15 | "cli",
16 | "microservices",
17 | "microfrontends",
18 | "SSR",
19 | "merkur",
20 | "widget",
21 | "react",
22 | "preact",
23 | "svelte"
24 | ],
25 | "repository": {
26 | "type": "git",
27 | "url": "git+https://github.com/mjancarik/merkur.git"
28 | },
29 | "author": "Miroslav Jancarik",
30 | "license": "ISC",
31 | "bugs": {
32 | "url": "https://github.com/mjancarik/merkur/issues"
33 | },
34 | "publishConfig": {
35 | "registry": "https://registry.npmjs.org/",
36 | "access": "public"
37 | },
38 | "engines": {
39 | "node": ">=12"
40 | },
41 | "dependencies": {
42 | "chalk": "^5.2.0",
43 | "execa": "^7.1.1",
44 | "fs-extra": "^11.1.1",
45 | "inquirer": "9.2.2",
46 | "yargs": "^17.7.2"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/tools/jest.config.js:
--------------------------------------------------------------------------------
1 | const testGroupRegexes = {
2 | unit: '(/__tests__/).*(Spec|test)\\.[jt]sx?$',
3 | integration: '(/__integration__/).*(Spec|test)\\.[jt]sx?$',
4 | all: '((/__integration__/)|(/__tests__/)).*(Spec|test)\\.[jt]sx?$',
5 | };
6 |
7 | const testGroup =
8 | process.env.TEST_GROUP &&
9 | Object.keys(testGroupRegexes).includes(process.env.TEST_GROUP)
10 | ? process.env.TEST_GROUP
11 | : 'all';
12 |
13 | module.exports = {
14 | bail: false,
15 | verbose: true,
16 | testEnvironment: 'node',
17 | modulePaths: ['/'],
18 | testRegex: testGroupRegexes[testGroup],
19 | testPathIgnorePatterns: ['/node_modules/', '/__snapshots__/'],
20 | transform: {
21 | '^.+\\.[t|j]sx?$': 'babel-jest',
22 | },
23 | watchPlugins: [
24 | require.resolve('jest-watch-typeahead/filename'),
25 | require.resolve('jest-watch-typeahead/testname'),
26 | ],
27 | // https://github.com/preactjs/preact/pull/3634
28 | testEnvironmentOptions: {
29 | customExportConditions: ['node', 'node-addons'],
30 | },
31 | moduleNameMapper: {
32 | '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
33 | '/__mocks__/fileMock.js',
34 | '\\.(css|less)$': 'identity-obj-proxy',
35 | },
36 | };
37 |
--------------------------------------------------------------------------------
/packages/plugin-http-cache/src/CacheEntry.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The cache entry is a typed container of cache data used to track the
3 | * creation and expiration of cache entries.
4 | */
5 | export default class CacheEntry {
6 | /**
7 | * Initializes the cache entry.
8 | *
9 | * @param {*} value The cache entry value.
10 | * @param {number} ttl The time to live in milliseconds.
11 | */
12 | constructor(value, ttl) {
13 | this._value = value;
14 | this._ttl = ttl;
15 | this._created = Date.now();
16 | }
17 |
18 | /**
19 | * Returns the entry value.
20 | *
21 | * @return {*} The entry value.
22 | */
23 | get value() {
24 | return this._value;
25 | }
26 |
27 | /**
28 | * Returns `true` if this entry has expired.
29 | *
30 | * @return {boolean} `true` if this entry has expired.
31 | */
32 | isExpired() {
33 | let now = Date.now();
34 | return now > this._created + this._ttl;
35 | }
36 |
37 | /**
38 | * Exports this cache entry into a JSON-serializable object.
39 | *
40 | * @return {{value: *, ttl: number}} This entry exported to a
41 | * JSON-serializable object.
42 | */
43 | serialize() {
44 | return {
45 | value: this.value,
46 | ttl: this._ttl === Infinity ? 'Infinity' : this._ttl,
47 | };
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/packages/cli/src/websocket.mjs:
--------------------------------------------------------------------------------
1 | import WebSocket, { WebSocketServer } from 'ws';
2 |
3 | function broadcastMessage(server, fromClient, data) {
4 | server.clients.forEach(function each(toClient) {
5 | sendMessage(fromClient, toClient, data);
6 | });
7 | }
8 |
9 | function sendMessage(fromClient, toClient, data) {
10 | if (toClient !== fromClient && toClient.readyState === WebSocket.OPEN) {
11 | toClient.send(data);
12 | }
13 | }
14 |
15 | export async function runSocketServer({ merkurConfig, context }) {
16 | try {
17 | const server = new WebSocketServer({
18 | port: merkurConfig.socketServer.port,
19 | });
20 |
21 | server.on('connection', function connection(ws) {
22 | ws.on('message', function incomingMessage(data, isBinary) {
23 | data = isBinary ? data : data.toString();
24 | broadcastMessage(server, ws, data);
25 | });
26 | });
27 |
28 | context.server.socketServer = server;
29 | } catch (error) {
30 | throw new Error(
31 | `Unable to create socket server on port ${merkurConfig.socketServer.port}.`,
32 | { cause: error },
33 | );
34 | }
35 | }
36 |
37 | export function createClient({ merkurConfig }) {
38 | const { protocol, host } = merkurConfig.socketServer;
39 |
40 | return new WebSocket(`${protocol}//${host}`);
41 | }
42 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/test.mjs:
--------------------------------------------------------------------------------
1 | import { spawn } from 'node:child_process';
2 | import process from 'node:process';
3 |
4 | import { npmRunPath } from 'npm-run-path';
5 |
6 | import { createCommandConfig } from '../commandConfig.mjs';
7 | import { createLogger } from '../logger.mjs';
8 | import { handleExit } from '../handleExit.mjs';
9 |
10 | export async function test({ args, commandArgs, command }) {
11 | const { context, cliConfig, merkurConfig } = await createCommandConfig({
12 | args,
13 | command,
14 | });
15 | const logger = createLogger('testRunner', cliConfig);
16 |
17 | await handleExit({ context });
18 |
19 | commandArgs.unshift('./jest.config.js');
20 | commandArgs.unshift('-c');
21 |
22 | const runner = spawn('jest', commandArgs, {
23 | env: {
24 | ...process.env,
25 | PATH: npmRunPath(),
26 | NODE_CONFIG_DIR: './server/config',
27 | MERKUR_CONFIG: JSON.stringify(merkurConfig),
28 | CLI_CONFIG: JSON.stringify(cliConfig),
29 | },
30 | stdio: 'inherit',
31 | });
32 |
33 | runner.on('spawn', () => {
34 | logger.debug(`Run test runner ${commandArgs.join(', ')}`);
35 | });
36 | runner.on('exit', (code, signal) => {
37 | logger.info(`child process exited with code ${code} and signal ${signal}`);
38 | process.exit(code);
39 | });
40 | }
41 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/src/__tests__/indexSpec.js:
--------------------------------------------------------------------------------
1 | import { createMerkurWidget } from '@merkur/core';
2 | import { cssScramblePlugin } from '../index';
3 |
4 | describe('createWidget method with cssScramble plugin', () => {
5 | it('should create empty widget', async () => {
6 | const widget = await createMerkurWidget({
7 | $plugins: [cssScramblePlugin],
8 | name: 'my-widget',
9 | version: '1.0.0',
10 | classnameHashtable: ['gfgfg', ['szn'], ['view', 'component']],
11 | props: {
12 | param: 1,
13 | },
14 | assets: [
15 | {
16 | type: 'script',
17 | source: 'http://www.example.com/static/1.0.0/widget.js',
18 | },
19 | ],
20 | });
21 |
22 | expect(widget).toMatchInlineSnapshot(`
23 | {
24 | "$dependencies": {},
25 | "$external": {},
26 | "$in": {
27 | "classNameScrambler": [Function],
28 | },
29 | "$plugins": [
30 | {
31 | "create": [Function],
32 | "setup": [Function],
33 | },
34 | ],
35 | "cn": [Function],
36 | "create": [Function],
37 | "info": [Function],
38 | "name": "my-widget",
39 | "setup": [Function],
40 | "version": "1.0.0",
41 | }
42 | `);
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/packages/tool-storybook/src/index.js:
--------------------------------------------------------------------------------
1 | import { getMerkur } from '@merkur/core';
2 |
3 | function createWidgetLoader({ render, widgetProperties }) {
4 | let lastStory = {};
5 |
6 | return async (args) => {
7 | if (lastStory.widget && lastStory.name !== args.story) {
8 | lastStory.widget.unmount();
9 | lastStory = {};
10 | }
11 |
12 | if (!args?.args?.widget?.props) {
13 | return { widget: null };
14 | }
15 |
16 | return {
17 | widget: lastStory.widget
18 | ? lastStory.widget
19 | : await getMerkur()
20 | .create({ ...widgetProperties, ...args.args.widget })
21 | .then(async (widget) => {
22 | widget.$in.component.lifeCycle.mount = () => {};
23 | widget.$in.component.lifeCycle.update = () => {
24 | render();
25 | };
26 | widget.$in.component.lifeCycle.unmount = () => {};
27 |
28 | widget.state = args?.args?.widget?.state ?? {};
29 | widget.props = args?.args?.widget?.props ?? {};
30 | await widget.mount();
31 |
32 | lastStory = {
33 | widget,
34 | name: args.story,
35 | };
36 |
37 | return widget;
38 | }),
39 | };
40 | };
41 | }
42 |
43 | export { createWidgetLoader };
44 |
--------------------------------------------------------------------------------
/website/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "website",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "docusaurus": "docusaurus",
7 | "start": "docusaurus start",
8 | "build": "docusaurus build",
9 | "swizzle": "docusaurus swizzle",
10 | "deploy": "docusaurus deploy",
11 | "clear": "docusaurus clear",
12 | "serve": "docusaurus serve",
13 | "write-translations": "docusaurus write-translations",
14 | "write-heading-ids": "docusaurus write-heading-ids",
15 | "typecheck": "tsc"
16 | },
17 | "dependencies": {
18 | "@docusaurus/core": "3.8.1",
19 | "@docusaurus/preset-classic": "3.8.1",
20 | "@mdx-js/react": "^3.0.0",
21 | "clsx": "^2.0.0",
22 | "prism-react-renderer": "^2.3.0",
23 | "react": "^19.0.0",
24 | "react-dom": "^19.0.0"
25 | },
26 | "devDependencies": {
27 | "@docusaurus/module-type-aliases": "3.8.1",
28 | "@docusaurus/tsconfig": "3.8.1",
29 | "@docusaurus/types": "3.8.1",
30 | "typescript": "~5.6.2"
31 | },
32 | "browserslist": {
33 | "production": [
34 | ">0.5%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "last 3 chrome version",
40 | "last 3 firefox version",
41 | "last 5 safari version"
42 | ]
43 | },
44 | "engines": {
45 | "node": ">=18.0"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/packages/plugin-error/server/index.js:
--------------------------------------------------------------------------------
1 | const DEV = 'development';
2 | const ENV =
3 | typeof process !== 'undefined' && process && process.env
4 | ? process.env.NODE_ENV
5 | : DEV;
6 |
7 | /**
8 | * Simple Express middleware to return widget-like JSON on error that couldn't be handled by plugin-error.
9 | *
10 | * @returns {function}
11 | */
12 | // eslint-disable-next-line no-unused-vars
13 | function apiErrorMiddleware() {
14 | //eslint-disable-next-line no-unused-vars
15 | return (error, req, res, next) => {
16 | // error handling for widget API
17 | const errorStatus = error.status || 500;
18 |
19 | let errorJSON = {
20 | error: {
21 | status: errorStatus,
22 | message: error.message || 'Unknown error',
23 | },
24 | };
25 |
26 | if (ENV === DEV) {
27 | errorJSON.error.stack = error.stack;
28 | }
29 |
30 | res.status(errorStatus).json(errorJSON);
31 | };
32 | }
33 |
34 | /**
35 | * Simple Express middleware to log error to console.
36 | *
37 | * @returns {function}
38 | */
39 | // eslint-disable-next-line no-unused-vars
40 | function logErrorMiddleware() {
41 | //eslint-disable-next-line no-unused-vars
42 | return (error, req, res, next) => {
43 | console.error(error);
44 | next(error);
45 | };
46 | }
47 |
48 | module.exports = {
49 | logErrorMiddleware,
50 | apiErrorMiddleware,
51 | };
52 |
--------------------------------------------------------------------------------
/packages/tools/websocket.cjs:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const WebSocket = require('ws');
4 |
5 | function broadcastMessage(server, fromClient, data) {
6 | server.clients.forEach(function each(toClient) {
7 | sendMessage(fromClient, toClient, data);
8 | });
9 | }
10 |
11 | function sendMessage(fromClient, toClient, data) {
12 | if (toClient !== fromClient && toClient.readyState === WebSocket.OPEN) {
13 | toClient.send(data);
14 | }
15 | }
16 |
17 | function createServer(options = {}) {
18 | options = Object.assign(
19 | {},
20 | { port: process.env.MERKUR_PLAYGROUND_LIVERELOAD_PORT },
21 | options,
22 | );
23 |
24 | let server = null;
25 |
26 | try {
27 | server = new WebSocket.Server(options);
28 | server.on('connection', function connection(ws) {
29 | ws.on('message', function incoming(data, isBinary) {
30 | data = isBinary ? data : data.toString();
31 | broadcastMessage(server, ws, data);
32 | });
33 | });
34 | } catch (error) {
35 | console.error(error);
36 | }
37 |
38 | return server;
39 | }
40 |
41 | function createClient(options) {
42 | options = Object.assign(
43 | {},
44 | { port: process.env.MERKUR_PLAYGROUND_LIVERELOAD_PORT },
45 | options,
46 | );
47 |
48 | return new WebSocket('ws://localhost:' + options.port);
49 | }
50 |
51 | module.exports = {
52 | createServer,
53 | createClient,
54 | };
55 |
--------------------------------------------------------------------------------
/packages/tool-storybook/README.md:
--------------------------------------------------------------------------------
1 | # Merkur - tool-storybook
2 |
3 | [](https://travis-ci.com/mjancarik/merkur)
4 | [](https://www.npmjs.com/package/@merkur/tool-storybook)
5 | 
6 | [](https://github.com/prettier/prettier)
7 |
8 | The module enables integration of [Storybook](https://storybook.js.org/) into [Merkur](https://merkur.js.org/).
9 |
10 | **[Documentation for @merkur/tool-storybook](https://merkur.js.org/docs/storybook-integration-into-merkur).**
11 |
12 | ## About Merkur
13 |
14 | The [Merkur](https://merkur.js.org/) is tiny extensible javascript library for front-end microservices. It allows by default server side rendering for loading performance boost. You can connect it with other frameworks or languages because merkur defines easy API. You can use one of four predefined template's library [Preact](https://preactjs.com/), [µhtml](https://github.com/WebReflection/uhtml#readme), [Svelte](https://svelte.dev/) and [vanilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) but you can easily extend for others.
15 |
--------------------------------------------------------------------------------
/packages/plugin-select-preact/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | # [0.44.0](https://github.com/mjancarik/merkur/compare/v0.43.1...v0.44.0) (2025-12-17)
7 |
8 | **Note:** Version bump only for package @merkur/plugin-select-preact
9 |
10 | # [0.43.0](https://github.com/mjancarik/merkur/compare/v0.42.0...v0.43.0) (2025-12-05)
11 |
12 | **Note:** Version bump only for package @merkur/plugin-select-preact
13 |
14 | # [0.42.0](https://github.com/mjancarik/merkur/compare/v0.41.1...v0.42.0) (2025-11-28)
15 |
16 | **Note:** Version bump only for package @merkur/plugin-select-preact
17 |
18 | # [0.41.0](https://github.com/mjancarik/merkur/compare/v0.40.0...v0.41.0) (2025-11-04)
19 |
20 | **Note:** Version bump only for package @merkur/plugin-select-preact
21 |
22 | # [0.40.0](https://github.com/mjancarik/merkur/compare/v0.39.0...v0.40.0) (2025-10-27)
23 |
24 | **Note:** Version bump only for package @merkur/plugin-select-preact
25 |
26 | # [0.39.0](https://github.com/mjancarik/merkur/compare/v0.38.2...v0.39.0) (2025-10-27)
27 |
28 | **Note:** Version bump only for package @merkur/plugin-select-preact
29 |
30 | ## [0.38.2](https://github.com/mjancarik/merkur/compare/v0.38.1...v0.38.2) (2025-09-11)
31 |
32 | **Note:** Version bump only for package @merkur/plugin-select-preact
33 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/views/__tests__/ViewSpec.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * @jest-environment jsdom
3 | */
4 | import {
5 | render,
6 | fireEvent,
7 | cleanup,
8 | prettyDOM,
9 | screen,
10 | } from '@testing-library/preact';
11 |
12 | import { createMerkurWidget } from '@merkur/core';
13 |
14 | import widgetProperties from '../../widget';
15 | import View from '../View';
16 |
17 | describe('View', () => {
18 | let widget = null;
19 |
20 | beforeEach(async () => {
21 | widget = await createMerkurWidget({
22 | ...widgetProperties,
23 | mount(widget) {
24 | widget.$external.result = render(View(widget));
25 | return widget.$external.result;
26 | },
27 | unmount() {
28 | cleanup();
29 | },
30 | update() {
31 | return widget.$external.result.rerender(View(widget));
32 | },
33 | });
34 | });
35 |
36 | afterEach(() => {
37 | widget.unmount();
38 | });
39 |
40 | it('should display main view', async () => {
41 | const { container } = await widget.mount();
42 |
43 | expect(prettyDOM(container)).toMatchSnapshot();
44 | });
45 |
46 | it('should increase counter', async () => {
47 | const { container } = await widget.mount();
48 |
49 | const button = screen.getByText('increase counter');
50 |
51 | fireEvent.click(button);
52 |
53 | expect(prettyDOM(container)).toMatchSnapshot();
54 | });
55 | });
56 |
--------------------------------------------------------------------------------
/utils/restoreLatestTag.mjs:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | import child_process from 'child_process';
3 | import { promisify } from 'util';
4 |
5 | const exec = promisify(child_process.exec);
6 |
7 | function isStable(version) {
8 | return version.match(/^\d+\.\d+\.\d+$/);
9 | }
10 |
11 | (async () => {
12 | const version = process.env.npm_package_version;
13 |
14 | const packageName = process.env.npm_package_name;
15 | if (!version || !packageName) {
16 | return;
17 | }
18 |
19 | try {
20 | if (!isStable(version)) {
21 | console.log('This version is a pre-release.');
22 |
23 | const { stdout } = await exec(`npm info ${packageName} versions --json`);
24 | const versions = JSON.parse(stdout);
25 |
26 | let lastStable = null;
27 | let ver = versions.pop();
28 | while (!lastStable && versions.length) {
29 | ver = versions.pop();
30 | lastStable = isStable(ver) ? ver : null;
31 | }
32 |
33 | if (!lastStable) {
34 | console.log('No stable version found to restore.');
35 | return;
36 | }
37 |
38 | await exec(`npm dist-tag add ${packageName}@${lastStable} latest`);
39 | console.log(`Restored latest stable tag to version: ${lastStable}`);
40 | } else {
41 | console.log('This is a stable version.');
42 | }
43 | } catch (error) {
44 | console.error('Error restoring latest stable tag:', error);
45 | }
46 | })();
47 |
--------------------------------------------------------------------------------
/packages/cli/src/widgetServer.mjs:
--------------------------------------------------------------------------------
1 | import { spawn } from 'node:child_process';
2 | import process from 'node:process';
3 |
4 | import chalk from 'chalk';
5 |
6 | import { createLogger } from './logger.mjs';
7 |
8 | export async function runWidgetServer({ merkurConfig, cliConfig, context }) {
9 | const logger = createLogger('widgetServer', cliConfig);
10 | const { watch, inspect } = cliConfig;
11 | const { protocol, host } = merkurConfig.widgetServer;
12 |
13 | const args = [`./server/server.js`];
14 |
15 | if (watch) {
16 | args.unshift(`--watch-path=./server/`);
17 | args.unshift(`--watch-path=./node_modules/`);
18 | args.unshift(`--watch-preserve-output`);
19 | args.unshift('--watch');
20 | }
21 |
22 | if (inspect) {
23 | args.unshift('--inspect');
24 | }
25 |
26 | if (watch) logger.debug('Starting widget server with watch mode.');
27 | const server = spawn('node', args, {
28 | env: {
29 | NODE_CONFIG_DIR: './server/config',
30 | NODE_WATCH: watch,
31 | ...process.env,
32 | MERKUR_CONFIG: JSON.stringify(merkurConfig),
33 | CLI_CONFIG: JSON.stringify(cliConfig),
34 | },
35 | stdio: cliConfig.silent || cliConfig.quiet ? 'pipe' : 'inherit',
36 | });
37 |
38 | server.on('spawn', () => {
39 | logger.info(
40 | `Widget API endpoint: ${chalk.green(`${protocol}//${host}/widget`)}`,
41 | );
42 | });
43 |
44 | context.process.widgetServer = server;
45 | }
46 |
--------------------------------------------------------------------------------
/packages/plugin-component/README.md:
--------------------------------------------------------------------------------
1 | # Merkur - plugin-component
2 |
3 | [](https://travis-ci.com/mjancarik/merkur)
4 | [](https://www.npmjs.com/package/@merkur/plugin-component)
5 | 
6 | [](https://github.com/prettier/prettier)
7 |
8 | The component plugin is one of the base Merkur plugins which adds base lifecycle methods and properties to your widget. Other Merkur plugins can depend on it.
9 |
10 | **[Documentation for @merkur/plugin-component](https://merkur.js.org/docs/component-plugin).**
11 |
12 | ## About Merkur
13 |
14 | The [Merkur](https://merkur.js.org/) is tiny extensible javascript library for front-end microservices. It allows by default server side rendering for loading performance boost. You can connect it with other frameworks or languages because merkur defines easy API. You can use one of four predefined template's library [Preact](https://preactjs.com/), [µhtml](https://github.com/WebReflection/uhtml#readme), [Svelte](https://svelte.dev/) and [vanilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) but you can easily extend for others.
15 |
--------------------------------------------------------------------------------
/packages/svelte/cli/index.mjs:
--------------------------------------------------------------------------------
1 | import { fileURLToPath } from 'node:url';
2 |
3 | import sveltePlugin from 'esbuild-svelte';
4 |
5 | export default function ({ emitter, EMITTER_EVENTS, cliConfig }) {
6 | emitter.on(
7 | EMITTER_EVENTS.MERKUR_CONFIG,
8 | function defaultEntries({ merkurConfig }) {
9 | merkurConfig.defaultEntries = {
10 | client: [
11 | fileURLToPath(
12 | import.meta.resolve('@merkur/svelte/entries/client.js'),
13 | ),
14 | ],
15 | server: [
16 | fileURLToPath(
17 | import.meta.resolve('@merkur/svelte/entries/server.js'),
18 | ),
19 | ],
20 | };
21 |
22 | return merkurConfig;
23 | },
24 | );
25 |
26 | emitter.on(
27 | EMITTER_EVENTS.TASK_BUILD,
28 | function defaultBuild({ build, config }) {
29 | build = {
30 | ...build,
31 | mainFields: ['svelte', 'browser', 'module', 'main'],
32 | conditions: ['svelte', 'browser'],
33 | plugins: [
34 | ...build.plugins,
35 | sveltePlugin({
36 | compilerOptions: {
37 | dev: cliConfig.watch,
38 | generate: config.isServer ? 'ssr' : 'dom',
39 | hydratable: true,
40 | css: !config.isServer,
41 | },
42 | cache: cliConfig.watch,
43 | }),
44 | ],
45 | };
46 |
47 | return build;
48 | },
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/packages/create-widget/template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "merker-template",
3 | "version": "0.0.1",
4 | "description": "",
5 | "scripts": {
6 | "test": "npm run test:all",
7 | "test:unit": "cross-env TEST_GROUP='unit' merkur test",
8 | "test:integration": "cross-env TEST_GROUP='integration' merkur test",
9 | "test:all": "npm run build && cross-env TEST_GROUP='all' merkur test",
10 | "test:watch": "cross-env TEST_GROUP='unit' merkur test --watchAll",
11 | "lint": "eslint -c ./.eslintrc.js --ignore-path ./.prettierignore './**/*.{js,jsx}'",
12 | "dev": "merkur dev",
13 | "build": "merkur build",
14 | "start": "merkur start"
15 | },
16 | "author": "",
17 | "license": "ISC",
18 | "dependencies": {
19 | "@merkur/cli": "0.44.0",
20 | "@merkur/core": "0.44.0",
21 | "@merkur/integration": "0.44.0",
22 | "@merkur/plugin-component": "0.44.0",
23 | "@merkur/plugin-error": "0.44.0",
24 | "@merkur/plugin-event-emitter": "0.44.0",
25 | "compression": "^1.7.4",
26 | "config": "^3.3.7",
27 | "cors": "^2.8.5",
28 | "cross-env": "^7.0.3",
29 | "express": "^4.17.3",
30 | "express-static-gzip": "^2.1.5",
31 | "helmet": "^5.0.2",
32 | "morgan": "^1.10.0"
33 | },
34 | "devDependencies": {
35 | "@merkur/tools": "0.44.0",
36 | "es-jest": "^2.1.0"
37 | },
38 | "engines": {
39 | "node": ">=20.0.0"
40 | },
41 | "imports": {
42 | "#src/*": "./src/*"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/README.md:
--------------------------------------------------------------------------------
1 | # Merkur - plugin-event-emiter
2 |
3 | [](https://travis-ci.com/mjancarik/merkur)
4 | [](https://www.npmjs.com/package/@merkur/plugin-event-emitter)
5 | 
6 | [](https://github.com/prettier/prettier)
7 |
8 | The event emitter plugin is one of the base Merkur plugins which adds event methods to your widget. Other Merkur plugins can depend on it.
9 |
10 | **[Documentation for @merkur/plugin-event-emitter](https://merkur.js.org/docs/event-emitter-plugin).**
11 |
12 | ## About Merkur
13 |
14 | The [Merkur](https://merkur.js.org/) is tiny extensible javascript library for front-end microservices. It allows by default server side rendering for loading performance boost. You can connect it with other frameworks or languages because merkur defines easy API. You can use one of four predefined template's library [Preact](https://preactjs.com/), [µhtml](https://github.com/WebReflection/uhtml#readme), [Svelte](https://svelte.dev/) and [vanilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) but you can easily extend for others.
15 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/README.md:
--------------------------------------------------------------------------------
1 | # Merkur - plugin-http-client
2 |
3 | [](https://travis-ci.com/mjancarik/merkur)
4 | [](https://www.npmjs.com/package/@merkur/plugin-http-client)
5 | 
6 | [](https://github.com/prettier/prettier)
7 |
8 | The HTTP client plugin adds http property to your widget with a request method. Under the hood this plugin uses native browser fetch API and for server-side the node-fetch polyfill.
9 |
10 | **[Documentation for @merkur/plugin-http-client](https://merkur.js.org/docs/http-client-plugin).**
11 |
12 | ## About Merkur
13 |
14 | The [Merkur](https://merkur.js.org/) is tiny extensible javascript library for front-end microservices. It allows by default server side rendering for loading performance boost. You can connect it with other frameworks or languages because merkur defines easy API. You can use one of four predefined template's library [Preact](https://preactjs.com/), [µhtml](https://github.com/WebReflection/uhtml#readme), [Svelte](https://svelte.dev/) and [vanilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) but you can easily extend for others.
15 |
--------------------------------------------------------------------------------
/packages/cli/src/devClient/index.mjs:
--------------------------------------------------------------------------------
1 | import { createMerkur } from '@merkur/core';
2 |
3 | import { WebSocketClient } from './WebSocketClient.mjs';
4 |
5 | import { reload } from './reload.mjs';
6 | import { hmr } from './hmr.mjs';
7 |
8 | const MERKUR_CREATE_ORIGINAL = Symbol('MERKUR_CREATE_ORIGINAL');
9 | const { __merkur_dev__ } = window;
10 |
11 | const webSocket = new WebSocketClient(__merkur_dev__.merkurConfig.socketServer);
12 | __merkur_dev__.webSocket = webSocket;
13 | __merkur_dev__.widgets = [];
14 |
15 | webSocket.init();
16 |
17 | webSocket.subscribe(reload);
18 | webSocket.subscribe(hmr);
19 |
20 | if (window?.__merkur__?.create) {
21 | const originalMerkurCreate = window.__merkur__.create;
22 | window.__merkur__.create = async function devClientHook(...rest) {
23 | const widget = await originalMerkurCreate(...rest);
24 |
25 | __merkur_dev__.widgets.push(widget);
26 |
27 | return widget;
28 | };
29 | }
30 |
31 | function hookMerkurCreate() {
32 | if (
33 | window?.__merkur__?.create &&
34 | !window.__merkur__.create[MERKUR_CREATE_ORIGINAL]
35 | ) {
36 | const originalMerkurCreate = window.__merkur__.create;
37 |
38 | window.__merkur__.create = async function devClientHook(...rest) {
39 | const widget = await originalMerkurCreate(...rest);
40 |
41 | __merkur_dev__.widgets.push(widget);
42 |
43 | return widget;
44 | };
45 |
46 | window.__merkur__.create[MERKUR_CREATE_ORIGINAL] = originalMerkurCreate;
47 | }
48 | }
49 | createMerkur();
50 | hookMerkurCreate();
51 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/routes/widgetAPI/widgetAPI.js:
--------------------------------------------------------------------------------
1 | const config = require('config');
2 | const express = require('express');
3 |
4 | const { resolveConfig } = require('@merkur/cli/server');
5 | const {
6 | asyncMiddleware,
7 | createAssets,
8 | memo,
9 | requireUncached,
10 | } = require('@merkur/integration/server');
11 | const memoCreateAssets = memo(createAssets);
12 |
13 | const { merkurConfig, cliConfig } = resolveConfig();
14 | const { staticFolder, buildFolder, protocol, host, staticPath } =
15 | merkurConfig.widgetServer;
16 |
17 | const widgetEnvironment = config.get('widget');
18 |
19 | const router = express.Router();
20 | router.get(
21 | '/widget',
22 | asyncMiddleware(async (req, res) => {
23 | const merkurModule = requireUncached(`${buildFolder}/widget.cjs`);
24 | const widget = await merkurModule.createWidget({
25 | props: {
26 | name: req.query.name,
27 | environment: widgetEnvironment,
28 | },
29 | });
30 |
31 | const { html, slot = {} } = await widget.mount();
32 | const info = await widget.info();
33 |
34 | info.assets = await memoCreateAssets({
35 | assets: info.assets,
36 | staticFolder,
37 | staticBaseUrl: `${protocol}//${host}${staticPath}`,
38 | merkurConfig,
39 | cliConfig,
40 | });
41 |
42 | const status = info?.error?.status ?? 200;
43 |
44 | res.status(status).json({
45 | ...info,
46 | html,
47 | slot,
48 | });
49 | }),
50 | );
51 |
52 | module.exports = () => ({ router });
53 |
--------------------------------------------------------------------------------
/packages/create-widget/template/server/app.js:
--------------------------------------------------------------------------------
1 | const compression = require('compression');
2 | const cors = require('cors');
3 | const express = require('express');
4 | const expressStaticGzip = require('express-static-gzip');
5 | const helmet = require('helmet');
6 | const morgan = require('morgan');
7 |
8 | const { resolveConfig } = require('@merkur/cli/server');
9 |
10 | const {
11 | merkurConfig: { widgetServer },
12 | } = resolveConfig();
13 |
14 | const {
15 | apiErrorMiddleware,
16 | logErrorMiddleware,
17 | } = require('@merkur/plugin-error/server');
18 |
19 | const errorRouteFactory = require('./routes/error');
20 | const widgetAPIRouteFactory = require('./routes/widgetAPI');
21 |
22 | const error = errorRouteFactory();
23 | const widgetAPI = widgetAPIRouteFactory();
24 |
25 | const expressStaticConfig = {
26 | enableBrotli: true,
27 | index: false,
28 | orderPreference: ['br'],
29 | maxAge: '14d',
30 | };
31 |
32 | const app = express();
33 |
34 | app
35 | .use(morgan('dev'))
36 | .use(
37 | helmet({
38 | contentSecurityPolicy: false,
39 | crossOriginResourcePolicy: false,
40 | crossOriginEmbedderPolicy: false,
41 | }),
42 | )
43 | .use(cors(widgetServer.cors.options))
44 | .use(compression())
45 | .use(
46 | widgetServer.staticPath,
47 | expressStaticGzip(widgetServer.staticFolder, expressStaticConfig),
48 | )
49 | .use(widgetAPI.router)
50 | .use(error.router)
51 | .use(logErrorMiddleware())
52 | .use(apiErrorMiddleware());
53 |
54 | module.exports = {
55 | app,
56 | };
57 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/src/index.js:
--------------------------------------------------------------------------------
1 | import { assignMissingKeys } from '@merkur/core';
2 |
3 | export function eventEmitterPlugin() {
4 | return {
5 | async setup(widget) {
6 | assignMissingKeys(widget, eventEmitterAPI());
7 |
8 | widget.$in.eventEmitter = {
9 | event: {},
10 | };
11 |
12 | return widget;
13 | },
14 | };
15 | }
16 |
17 | function eventEmitterAPI() {
18 | return {
19 | on(widget, eventName, callback) {
20 | const {
21 | $in: {
22 | eventEmitter: { event },
23 | },
24 | } = widget;
25 |
26 | if (!event[eventName]) {
27 | event[eventName] = [];
28 | }
29 |
30 | event[eventName].push(callback);
31 |
32 | return widget;
33 | },
34 | off(widget, eventName, callback) {
35 | const {
36 | $in: {
37 | eventEmitter: { event },
38 | },
39 | } = widget;
40 |
41 | if (!event[eventName] || event[eventName].indexOf(callback) === -1) {
42 | return;
43 | }
44 |
45 | const position = event[eventName].indexOf(callback);
46 | event[eventName].splice(position, 1);
47 |
48 | return widget;
49 | },
50 | emit(widget, eventName, ...rest) {
51 | const {
52 | $in: {
53 | eventEmitter: { event },
54 | },
55 | } = widget;
56 |
57 | if (!event[eventName]) {
58 | return;
59 | }
60 |
61 | event[eventName].forEach((callback) => {
62 | callback(widget, ...rest);
63 | });
64 |
65 | return widget;
66 | },
67 | };
68 | }
69 |
--------------------------------------------------------------------------------
/website/src/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react';
2 | import clsx from 'clsx';
3 | import Link from '@docusaurus/Link';
4 | import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
5 | import Layout from '@theme/Layout';
6 | import HomepageFeatures from '@site/src/components/HomepageFeatures';
7 | import Heading from '@theme/Heading';
8 |
9 | import styles from './index.module.css';
10 |
11 | function HomepageHeader() {
12 | const { siteConfig } = useDocusaurusContext();
13 | return (
14 |
30 | );
31 | }
32 |
33 | export default function Home(): ReactNode {
34 | return (
35 |
39 |
40 |
41 |
42 |
43 |
44 | );
45 | }
46 |
--------------------------------------------------------------------------------
/packages/cli/src/server.mjs:
--------------------------------------------------------------------------------
1 | import process from 'node:process';
2 |
3 | import { createClient } from './websocket.mjs';
4 |
5 | let cliConfig, merkurConfig;
6 |
7 | export function resolveConfig() {
8 | if (process.env.CLI_CONFIG && !cliConfig) {
9 | cliConfig = JSON.parse(process.env.CLI_CONFIG);
10 | }
11 |
12 | if (process.env.MERKUR_CONFIG && !merkurConfig) {
13 | merkurConfig = JSON.parse(process.env.MERKUR_CONFIG);
14 | }
15 |
16 | return {
17 | merkurConfig,
18 | cliConfig,
19 | };
20 | }
21 |
22 | export function autoReload({ merkurConfig, cliConfig }) {
23 | function reload() {
24 | const client = createClient({ merkurConfig });
25 | client.on('error', (error) => {
26 | console.error(error);
27 | client.terminate();
28 | });
29 |
30 | client.on('open', function open() {
31 | setTimeout(() => {
32 | client.send(
33 | JSON.stringify({
34 | to: 'browser',
35 | command: 'reload',
36 | changed: [],
37 | errors: [],
38 | }),
39 | );
40 | client.terminate();
41 | }, 50);
42 | });
43 | }
44 |
45 | if (cliConfig.watch) {
46 | reload();
47 |
48 | const handleExit = () => process.exit(0);
49 | process.on('SIGINT', handleExit);
50 | process.on('SIGQUIT', handleExit);
51 | process.on('SIGTERM', handleExit);
52 |
53 | // TODO improve for error-overlay
54 | process.on('uncaughtException', () => {
55 | reload();
56 | });
57 |
58 | process.on('unhandledRejection', () => {
59 | reload();
60 | });
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/packages/create-widget/views/preact/template/src/widget.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import { defineWidget } from '@merkur/core';
3 | import {
4 | componentPlugin,
5 | createViewFactory,
6 | createSlotFactory,
7 | } from '@merkur/plugin-component';
8 | import { errorPlugin } from '@merkur/plugin-error';
9 | import { eventEmitterPlugin } from '@merkur/plugin-event-emitter';
10 |
11 | import HeadlineSlot from './slots/HeadlineSlot';
12 | import ErrorView from './views/ErrorView';
13 | import View from './views/View';
14 |
15 | import pkg from '../package.json';
16 |
17 | import './style.css';
18 |
19 | export default defineWidget({
20 | name: pkg.name,
21 | version: pkg.version,
22 | viewFactory: createViewFactory((widget) => ({
23 | View,
24 | ErrorView,
25 | slotFactories: [
26 | createSlotFactory((widget) => ({
27 | name: 'headline',
28 | View: HeadlineSlot,
29 | })),
30 | ],
31 | })),
32 | $plugins: [componentPlugin, eventEmitterPlugin, errorPlugin],
33 | assets: [
34 | {
35 | name: 'widget.js',
36 | type: 'script',
37 | },
38 | {
39 | name: 'widget.css',
40 | type: 'stylesheet',
41 | },
42 | ],
43 | onClick(widget) {
44 | widget.setState({ counter: widget.state.counter + 1 });
45 | },
46 | onReset(widget) {
47 | widget.setState({ counter: 0 });
48 | },
49 | load(widget) {
50 | // We don't want to set environment into app state
51 | const { environment, ...restProps } = widget.props;
52 |
53 | return {
54 | counter: 0,
55 | ...restProps,
56 | };
57 | },
58 | });
59 |
--------------------------------------------------------------------------------
/packages/create-widget/views/uhtml/template/src/widget.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import { defineWidget } from '@merkur/core';
3 | import {
4 | componentPlugin,
5 | createViewFactory,
6 | createSlotFactory,
7 | } from '@merkur/plugin-component';
8 | import { errorPlugin } from '@merkur/plugin-error';
9 | import { eventEmitterPlugin } from '@merkur/plugin-event-emitter';
10 |
11 | import HeadlineSlot from './slots/HeadlineSlot';
12 | import ErrorView from './views/ErrorView';
13 | import View from './views/View';
14 |
15 | import pkg from '../package.json';
16 |
17 | import './style.css';
18 |
19 | export default defineWidget({
20 | name: pkg.name,
21 | version: pkg.version,
22 | viewFactory: createViewFactory((widget) => ({
23 | View,
24 | ErrorView,
25 | slotFactories: [
26 | createSlotFactory((widget) => ({
27 | name: 'headline',
28 | View: HeadlineSlot,
29 | })),
30 | ],
31 | })),
32 | $plugins: [componentPlugin, eventEmitterPlugin, errorPlugin],
33 | assets: [
34 | {
35 | name: 'widget.js',
36 | type: 'script',
37 | },
38 | {
39 | name: 'widget.css',
40 | type: 'stylesheet',
41 | },
42 | ],
43 | onClick(widget) {
44 | widget.setState({ counter: widget.state.counter + 1 });
45 | },
46 | onReset(widget) {
47 | widget.setState({ counter: 0 });
48 | },
49 | load(widget) {
50 | // We don't want to set environment into app state
51 | const { environment, ...restProps } = widget.props;
52 |
53 | return {
54 | counter: 0,
55 | ...restProps,
56 | };
57 | },
58 | });
59 |
--------------------------------------------------------------------------------
/packages/plugin-error/README.md:
--------------------------------------------------------------------------------
1 | # Merkur - plugin-error
2 |
3 | [](https://travis-ci.com/mjancarik/merkur)
4 | [](https://www.npmjs.com/package/@merkur/plugin-error)
5 | 
6 | [](https://github.com/prettier/prettier)
7 |
8 | `merkur/plugin-error` adds semi-automatic error handling to your Merkur widget:
9 |
10 | * Return a custom HTTP status based on thrown error
11 | * Render valid JSON with error code and message
12 | * Render an error page
13 | * Run arbitrary code on error (e.g. to log/report the error)
14 | * Catch unhandled promise errors
15 |
16 |
17 | **[Full documentation for @merkur/plugin-error](https://merkur.js.org/docs/error-plugin).**
18 |
19 | ## About Merkur
20 |
21 | The [Merkur](https://merkur.js.org/) is tiny extensible javascript library for front-end microservices(micro frontends). It allows by default server side rendering for loading performance boost. You can connect it with other frameworks or languages because merkur defines easy API. You can use one of six predefined template's library [Preact](https://preactjs.com/), [µhtml](https://github.com/WebReflection/uhtml#readme), [Svelte](https://svelte.dev/) and [vanilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) but you can easily extend for others.
22 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/userDefined.mjs:
--------------------------------------------------------------------------------
1 | import path from 'node:path';
2 | import fs from 'node:fs';
3 |
4 | let userDefinedCommandsPaths = [];
5 |
6 | /**
7 | * Extend the commands from a directory
8 | * @param {string} commandsDir - The directory containing the commands
9 | * @returns {Promise}
10 | */
11 | const extendCommandsFromDir = async (commandsDir) => {
12 | userDefinedCommandsPaths = userDefinedCommandsPaths.concat(
13 | fs
14 | .readdirSync(commandsDir)
15 | .map((command) => ({ dir: commandsDir, command }))
16 | .filter(({ command, dir }) => {
17 | return (
18 | fs.statSync(path.join(dir, command)).isFile() &&
19 | (command.endsWith('.js') ||
20 | command.endsWith('.mjs') ||
21 | command.endsWith('.cjs'))
22 | );
23 | }),
24 | );
25 | };
26 |
27 | const existsMerkurConfig = fs
28 | .readdirSync(process.cwd())
29 | .includes('merkur.config.mjs');
30 |
31 | if (existsMerkurConfig) {
32 | const projectCommandsDir = path.resolve(process.cwd(), 'cli/commands');
33 | if (fs.existsSync(projectCommandsDir)) {
34 | await extendCommandsFromDir(projectCommandsDir);
35 | }
36 | const merkurDir = path.resolve(process.cwd(), 'node_modules/@merkur');
37 | if (fs.existsSync(merkurDir)) {
38 | let dirs = fs.readdirSync(merkurDir);
39 |
40 | for (const dir of dirs) {
41 | const fullPath = path.join(merkurDir, `${dir}/commands`);
42 | if (fs.existsSync(fullPath)) {
43 | await extendCommandsFromDir(fullPath);
44 | }
45 | }
46 | }
47 | }
48 |
49 | export { userDefinedCommandsPaths };
50 |
--------------------------------------------------------------------------------
/packages/create-widget/views/svelte/template/src/widget.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import { defineWidget } from '@merkur/core';
3 | import {
4 | componentPlugin,
5 | createViewFactory,
6 | createSlotFactory,
7 | } from '@merkur/plugin-component';
8 | import { errorPlugin } from '@merkur/plugin-error';
9 | import { eventEmitterPlugin } from '@merkur/plugin-event-emitter';
10 |
11 | import HeadlineSlot from './slots/HeadlineSlot.svelte';
12 | import ErrorView from './views/ErrorView.svelte';
13 | import View from './views/View.svelte';
14 |
15 | import pkg from '../package.json';
16 |
17 | import './style.css';
18 |
19 | export default defineWidget({
20 | name: pkg.name,
21 | version: pkg.version,
22 | viewFactory: createViewFactory((widget) => ({
23 | View,
24 | ErrorView,
25 | slotFactories: [
26 | createSlotFactory((widget) => ({
27 | name: 'headline',
28 | View: HeadlineSlot,
29 | })),
30 | ],
31 | })),
32 | $plugins: [componentPlugin, eventEmitterPlugin, errorPlugin],
33 | assets: [
34 | {
35 | name: 'widget.js',
36 | type: 'script',
37 | },
38 | {
39 | name: 'widget.css',
40 | type: 'stylesheet',
41 | },
42 | ],
43 | onClick(widget) {
44 | widget.setState({ counter: widget.state.counter + 1 });
45 | },
46 | onReset(widget) {
47 | widget.setState({ counter: 0 });
48 | },
49 | load(widget) {
50 | // We don't want to set environment into app state
51 | const { environment, ...restProps } = widget.props;
52 |
53 | return {
54 | counter: 0,
55 | ...restProps,
56 | };
57 | },
58 | });
59 |
--------------------------------------------------------------------------------
/packages/cli/src/templates/head.ejs:
--------------------------------------------------------------------------------
1 |
8 | <% assets.forEach((asset)=> { %>
9 | <%if (asset.type==='stylesheet' ) { %>
10 |
11 | <% } %>
12 | <%if (asset.type==='inlineStyle' ) { %>
13 |
16 | <% } %>
17 |
18 | <%if (asset.type==='script' ) { %>
19 | <%if (typeof asset.source==='string' ) { %>
20 |
21 | <% } %>
22 | <%if (typeof asset.source==='object' ) { %>
23 |
24 | <% } %>
25 | <% } %>
26 |
27 | <%if (asset.type==='inlineScript' ) { %>
28 | <%if (typeof asset.source==='string' ) { %>
29 |
32 | <% } %>
33 | <%if (typeof asset.source==='object' ) { %>
34 |
37 | <% } %>
38 | <% } %>
39 | <% }); %>
40 |
--------------------------------------------------------------------------------
/packages/cli/src/commands/custom.mjs:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs/promises';
2 | import path from 'node:path';
3 |
4 | import chalk from 'chalk';
5 |
6 | import { createCommandConfig } from '../commandConfig.mjs';
7 | import { createLogger } from '../logger.mjs';
8 | import { handleExit } from '../handleExit.mjs';
9 |
10 | export const CUSTOM_PART = {
11 | PLAYGROUND_BODY: 'playground:body',
12 | PLAYGROUND_FOOTER: 'playground:footer',
13 | };
14 |
15 | export async function custom({ args, command }) {
16 | const { context, cliConfig, merkurConfig } = await createCommandConfig({
17 | args,
18 | command,
19 | });
20 | const logger = createLogger('Custom command:', cliConfig);
21 |
22 | await handleExit({ context });
23 |
24 | let file = null;
25 |
26 | switch (args.part) {
27 | case CUSTOM_PART.PLAYGROUND_BODY: {
28 | file = 'body.ejs';
29 | break;
30 | }
31 | case CUSTOM_PART.PLAYGROUND_FOOTER: {
32 | file = 'footer.ejs';
33 | break;
34 | }
35 | }
36 |
37 | if (file) {
38 | const src = path.resolve(
39 | `${merkurConfig.playground.templateFolder}/${file}`,
40 | );
41 | const dest = path.resolve(
42 | `${merkurConfig.playground.serverTemplateFolder}/${file}`,
43 | );
44 | const dirFolder = path.dirname(dest);
45 |
46 | logger.debug(`Create directory ${dirFolder}`);
47 | await fs.mkdir(dirFolder, { recursive: true });
48 |
49 | logger.debug(`Copy file from ${src} to ${dest}`);
50 | await fs.copyFile(src, dest);
51 |
52 | logger.info(`You can customize ${chalk.green(dest)} file.`);
53 | } else {
54 | logger.warn(`You define unknown part ${args.part}`);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/create-widget/views/vanilla/template/src/entries/client.js:
--------------------------------------------------------------------------------
1 | import { createMerkurWidget, createMerkur } from '@merkur/core';
2 |
3 | import { mapViews } from '@merkur/plugin-component/helpers';
4 | import { viewFactory } from '../views/View';
5 | import widgetProperties from '@widget';
6 |
7 | import '../style.css';
8 |
9 | function createWidget(widgetParams) {
10 | return createMerkurWidget({
11 | ...widgetProperties,
12 | ...widgetParams,
13 | $dependencies: {},
14 | async mount(widget) {
15 | mapViews(widget, viewFactory, ({ container }) => {
16 | if (!container) {
17 | return;
18 | }
19 |
20 | container
21 | .querySelector(`[data-merkur="on-increase"]`)
22 | ?.addEventListener('click', () => {
23 | widget.onClick();
24 | });
25 |
26 | container
27 | .querySelector(`[data-merkur="on-reset"]`)
28 | ?.addEventListener('click', () => {
29 | widget.onReset();
30 | });
31 | });
32 | },
33 | async unmount(widget) {
34 | mapViews(widget, viewFactory, ({ container }) => {
35 | if (!container) {
36 | return;
37 | }
38 |
39 | container.innerHTML = '';
40 | });
41 | },
42 | async update(widget) {
43 | mapViews(widget, viewFactory, ({ container }) => {
44 | if (!container) {
45 | return;
46 | }
47 |
48 | container.querySelector(`[data-merkur="counter"]`).innerText =
49 | widget.state.counter;
50 | });
51 | },
52 | });
53 | }
54 |
55 | const merkur = createMerkur();
56 | merkur.register({
57 | ...widgetProperties,
58 | createWidget,
59 | });
60 |
--------------------------------------------------------------------------------
/packages/plugin-css-scrambler/src/scramblerFactory.js:
--------------------------------------------------------------------------------
1 | import classnames from 'classnames';
2 | import numberToCssClass from './numberToCssClass';
3 |
4 | /**
5 | * @param {Array, Array>=} hashingTable
6 | * @return {function(...?(string|Object))}
7 | */
8 | export default function scramblerFactory(hashingTable) {
9 | let uniqueHash, prefixes, mainParts;
10 | const prefixTable = hashingTable && new Map();
11 | const mainPartTable = hashingTable && new Map();
12 |
13 | if (hashingTable) {
14 | [uniqueHash, prefixes, mainParts] = hashingTable;
15 | for (let i = 0; i < prefixes.length; i++) {
16 | prefixTable.set(prefixes[i], numberToCssClass(i));
17 | }
18 | for (let i = 0; i < mainParts.length; i++) {
19 | mainPartTable.set(mainParts[i], numberToCssClass(i));
20 | }
21 | }
22 |
23 | return (widget, ...args) => {
24 | const classNamesSource = classnames(...args);
25 | if (!hashingTable) {
26 | return {
27 | className: classNamesSource,
28 | };
29 | }
30 |
31 | const processedClasses = classNamesSource
32 | .split(/\s+/)
33 | .map((className) => {
34 | const parts = className.split('-');
35 | const prefix = parts[0];
36 | const mainPart = parts.slice(1).join('-');
37 | if (!prefixTable.has(prefix) || !mainPartTable.has(mainPart)) {
38 | return className;
39 | }
40 |
41 | return `${prefixTable.get(prefix)}_${mainPartTable.get(
42 | mainPart,
43 | )}_${uniqueHash}`;
44 | })
45 | .join(' ');
46 |
47 | return {
48 | className: processedClasses,
49 | 'data-class': classNamesSource,
50 | };
51 | };
52 | }
53 |
--------------------------------------------------------------------------------
/packages/cli/src/CLIConfig.mjs:
--------------------------------------------------------------------------------
1 | import { EMITTER_EVENTS, emitter, RESULT_KEY } from './emitter.mjs';
2 |
3 | export async function createCLIConfig({ args, command } = {}) {
4 | const environment = process.env.NODE_ENV;
5 | const isProduction = environment === 'production';
6 |
7 | return {
8 | analyze: args.analyze ?? false,
9 | buildFolder: args?.buildFolder ?? './build',
10 | cliFolder: import.meta.dirname,
11 | command: command ?? 'unknown',
12 | devServerPort: args?.devServerPort ?? 4445,
13 | environment,
14 | hasRunDevServer: args?.hasRunDevServer ?? false,
15 | hasRunWidgetServer: args?.hasRunWidgetServer ?? false,
16 | inspect: args.inspect ?? false,
17 | isProduction,
18 | outFile: args?.outFile ?? './build/widget.cjs',
19 | playgroundPath: args?.playgroundPath,
20 | port: args?.port ?? 4444,
21 | projectFolder: args?.projectFolder ?? process.cwd(),
22 | quiet: args?.quiet ?? false,
23 | runTasks: args?.runTasks ?? [],
24 | silent: args?.silent ?? false,
25 | sourcemap: args?.sourcemap ?? !isProduction,
26 | staticFolder: args?.staticFolder ?? './build/static',
27 | staticPath: args?.staticPath ?? '/static',
28 | staticPlayground: args?.staticPlayground ?? './build-playground',
29 | verbose: args.verbose ?? false,
30 | watch: args?.watch ?? !isProduction,
31 | writeToDisk: args?.writeToDisk ?? isProduction,
32 | };
33 | }
34 |
35 | export async function updateCLIConfig({ cliConfig, context, args }) {
36 | let event = {
37 | cliConfig,
38 | context,
39 | args,
40 | [RESULT_KEY]: 'cliConfig',
41 | };
42 |
43 | event = await emitter.emit(EMITTER_EVENTS.CLI_CONFIG, event);
44 |
45 | return event.cliConfig;
46 | }
47 |
--------------------------------------------------------------------------------
/packages/uhtml/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/uhtml",
3 | "version": "0.44.0",
4 | "description": "Collection of helpers to aid with Svelte integration to @merkur",
5 | "scripts": {
6 | "test": "echo 'Tests pass.'",
7 | "test:es:version": "echo 'Tests pass.'",
8 | "build": "rollup -c rollup.config.mjs",
9 | "dev": "rollup -c rollup.config.mjs -w",
10 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
11 | },
12 | "exports": {
13 | "./entries/client.js": "./entries/client.js",
14 | "./entries/server.js": "./entries/server.js",
15 | "./webpack": "./webpack/index.js",
16 | "./cli": "./cli/index.mjs",
17 | "./client": {
18 | "types": "./lib/client/client.d.ts",
19 | "import": "./lib/client/client.mjs",
20 | "require": "./lib/client/client.cjs"
21 | },
22 | "./server": {
23 | "types": "./lib/server/server.d.ts",
24 | "import": "./lib/server/server.mjs",
25 | "require": "./lib/server/server.cjs"
26 | }
27 | },
28 | "keywords": [
29 | "merkur",
30 | "uhtml",
31 | "micro",
32 | "frontend"
33 | ],
34 | "repository": {
35 | "type": "git",
36 | "url": "git+https://github.com/mjancarik/merkur.git"
37 | },
38 | "author": "Jan Šimeček",
39 | "license": "ISC",
40 | "bugs": {
41 | "url": "https://github.com/mjancarik/merkur/issues"
42 | },
43 | "publishConfig": {
44 | "registry": "https://registry.npmjs.org/",
45 | "access": "public"
46 | },
47 | "peerDependencies": {
48 | "@merkur/core": ">=0.34",
49 | "@merkur/plugin-component": ">=0.34",
50 | "@merkur/tool-webpack": ">=0.28"
51 | },
52 | "dependencies": {
53 | "ucontent": "^2.0.0",
54 | "uhtml": "^4.7.1"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/cli/src/utils.mjs:
--------------------------------------------------------------------------------
1 | export function time() {
2 | const start = process.hrtime.bigint();
3 |
4 | return () => Number((process.hrtime.bigint() - start) / BigInt(1e6));
5 | }
6 |
7 | const PROTECTED_FIELDS = ['__proto__', 'prototype', 'constructor'];
8 | export function deepMerge(target, source) {
9 | const isObject = (obj) => !!obj && obj.constructor === Object;
10 |
11 | if (!isObject(target) || !isObject(source)) {
12 | return source;
13 | }
14 |
15 | Object.keys(source).forEach((key) => {
16 | if (PROTECTED_FIELDS.includes(key)) {
17 | return;
18 | }
19 |
20 | const targetValue = target[key];
21 | const sourceValue = source[key];
22 |
23 | if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
24 | target[key] = targetValue.concat(sourceValue);
25 | } else if (isObject(targetValue) && isObject(sourceValue)) {
26 | target[key] = deepMerge(Object.assign({}, targetValue), sourceValue);
27 | } else {
28 | target[key] = sourceValue;
29 | }
30 | });
31 |
32 | return target;
33 | }
34 |
35 | export function addServerConfig(serverConfig, { protocol, hostname, port }) {
36 | if (protocol) {
37 | serverConfig.protocol = protocol;
38 | }
39 | if (port) {
40 | serverConfig.port = port;
41 | }
42 |
43 | const effectiveHostname =
44 | hostname ?? (port ? serverConfig.host?.split(':')[0] : null);
45 |
46 | if (effectiveHostname) {
47 | serverConfig.host = `${effectiveHostname}:${serverConfig.port}`;
48 | }
49 |
50 | if (serverConfig.protocol && serverConfig.host) {
51 | serverConfig.origin = new URL(
52 | `${serverConfig.protocol}//${serverConfig.host}`,
53 | ).origin;
54 | }
55 |
56 | return serverConfig;
57 | }
58 |
--------------------------------------------------------------------------------
/packages/plugin-component/src/helpers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Utility function to iterate thorugh views returned from
3 | * view factory and call callback function with view arguments
4 | * on each them.
5 | */
6 | export async function mapViews(widget, viewFactory, callback) {
7 | if (widget.$in.component.resolvedViews.has(viewFactory)) {
8 | return mapResolvedViews(
9 | widget.$in.component.resolvedViews.get(viewFactory) ?? [],
10 | callback,
11 | );
12 | }
13 |
14 | const { containerSelector } = widget;
15 | const { View, ErrorView, slot = {} } = await viewFactory(widget);
16 |
17 | // Add additional slot information to slot views
18 | const slots = Object.keys(widget.slot ?? {}).reduce((acc, cur) => {
19 | acc[cur] = {
20 | ...slot[cur],
21 | isSlot: true,
22 | containerSelector: widget.slot[cur]?.containerSelector,
23 | container: widget.slot[cur]?.container,
24 | };
25 |
26 | return acc;
27 | }, {});
28 |
29 | const views = [
30 | {
31 | View,
32 | ErrorView,
33 | containerSelector,
34 | isSlot: false,
35 | container: widget.container,
36 | },
37 | ...Object.values(slots),
38 | ];
39 |
40 | widget.$in.component.resolvedViews.set(viewFactory, views);
41 |
42 | return mapResolvedViews(views, callback);
43 | }
44 |
45 | function mapResolvedViews(views, callback) {
46 | return views.map(
47 | ({ View, ErrorView, containerSelector, isSlot, container }) => {
48 | callback({
49 | View,
50 | ErrorView,
51 | isSlot,
52 | containerSelector,
53 | container:
54 | (containerSelector && document?.querySelector(containerSelector)) ||
55 | container ||
56 | null,
57 | });
58 | },
59 | );
60 | }
61 |
--------------------------------------------------------------------------------
/packages/svelte/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/svelte",
3 | "version": "0.44.0",
4 | "description": "Collection of helpers to aid with Svelte integration to @merkur",
5 | "scripts": {
6 | "test": "echo 'Tests pass.'",
7 | "test:es:version": "echo 'Tests pass.'",
8 | "build": "rollup -c rollup.config.mjs",
9 | "dev": "rollup -c rollup.config.mjs -w",
10 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
11 | },
12 | "exports": {
13 | "./entries/client.js": "./entries/client.js",
14 | "./entries/server.js": "./entries/server.js",
15 | "./webpack": "./webpack/index.js",
16 | "./cli": "./cli/index.mjs",
17 | "./client": {
18 | "types": "./lib/client/client.d.ts",
19 | "import": "./lib/client/client.mjs",
20 | "require": "./lib/client/client.cjs"
21 | },
22 | "./server": {
23 | "types": "./lib/server/server.d.ts",
24 | "import": "./lib/server/server.mjs",
25 | "require": "./lib/server/server.cjs"
26 | }
27 | },
28 | "keywords": [
29 | "merkur",
30 | "svelte",
31 | "micro",
32 | "frontend"
33 | ],
34 | "repository": {
35 | "type": "git",
36 | "url": "git+https://github.com/mjancarik/merkur.git"
37 | },
38 | "author": "Jan Šimeček",
39 | "license": "ISC",
40 | "bugs": {
41 | "url": "https://github.com/mjancarik/merkur/issues"
42 | },
43 | "publishConfig": {
44 | "registry": "https://registry.npmjs.org/",
45 | "access": "public"
46 | },
47 | "peerDependencies": {
48 | "@merkur/core": ">=0.34",
49 | "@merkur/plugin-component": ">=0.34",
50 | "@merkur/tool-webpack": ">=0.28"
51 | },
52 | "dependencies": {
53 | "esbuild-svelte": "^0.8.0",
54 | "svelte": "^3.59.2",
55 | "svelte-loader": "^3.2.0"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/plugin-session-storage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/plugin-session-storage",
3 | "version": "0.44.0",
4 | "description": "Merkur session storage.",
5 | "main": "lib/index",
6 | "module": "lib/index",
7 | "unpkg": "lib/index.umd.js",
8 | "sideEffects": false,
9 | "exports": {
10 | ".": {
11 | "import": "./lib/index.mjs",
12 | "require": "./lib/index.cjs"
13 | },
14 | "./lib/index.es9.mjs": "./lib/index.es9.mjs",
15 | "./lib/index.es9.cjs": "./lib/index.es9.cjs"
16 | },
17 | "browser": {
18 | "./lib/index.js": "./lib/index.js",
19 | "./lib/index.cjs": "./lib/index.cjs",
20 | "./lib/index.mjs": "./lib/index.mjs",
21 | "./lib/index.es9.mjs": "./lib/index.es9.mjs"
22 | },
23 | "scripts": {
24 | "preversion": "npm test",
25 | "test": "jest --no-watchman -c ./jest.config.js",
26 | "test:es:version": "es-check es11 ./lib/index.mjs --module && es-check es9 ./lib/index.es9.mjs --module && es-check es9 ./lib/index.es9.cjs --module",
27 | "build": "rollup -c rollup.config.mjs",
28 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
29 | },
30 | "repository": {
31 | "type": "git",
32 | "url": "git+https://github.com/mjancarik/merkur.git"
33 | },
34 | "keywords": [
35 | "merkur",
36 | "plugin",
37 | "microservices",
38 | "microfrontends"
39 | ],
40 | "author": "Ondřej Baše",
41 | "license": "ISC",
42 | "bugs": {
43 | "url": "https://github.com/mjancarik/merkur/issues"
44 | },
45 | "publishConfig": {
46 | "registry": "https://registry.npmjs.org/",
47 | "access": "public"
48 | },
49 | "homepage": "https://merkur.js.org/",
50 | "devDependencies": {
51 | "@merkur/core": "^0.44.0"
52 | },
53 | "peerDependencies": {
54 | "@merkur/core": "*"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/cli/src/devClient/WebSocketClient.mjs:
--------------------------------------------------------------------------------
1 | import { Observable } from '@esmj/observable';
2 |
3 | const MAX_RECONNECTION = 5;
4 |
5 | export class WebSocketClient extends Observable {
6 | /**
7 | * @type {?WebSocket}
8 | */
9 | #socket = null;
10 | #reconnectionAttempt = 0;
11 | #options = {};
12 |
13 | constructor(options) {
14 | super();
15 | /**
16 | * @type {Object}
17 | */
18 | this.#options = options;
19 | }
20 |
21 | init() {
22 | this.#connect();
23 |
24 | return this;
25 | }
26 |
27 | send(data) {
28 | if (this.#socket) {
29 | this.#socket.send(data);
30 | }
31 |
32 | return this;
33 | }
34 |
35 | destroy() {
36 | if (this.#socket) {
37 | this.#socket.close();
38 | this.#socket = null;
39 | }
40 |
41 | return this;
42 | }
43 |
44 | #connect() {
45 | this.#socket = Reflect.construct(WebSocket, [
46 | `${this.#options.protocol}//${this.#options.host}`,
47 | ]);
48 |
49 | this.#socket.onopen = () => {
50 | this.#reconnectionAttempt = 0;
51 | };
52 |
53 | this.#socket.onmessage = (event) => {
54 | try {
55 | let data = JSON.parse(event.data);
56 |
57 | this.next(data);
58 | } catch (error) {
59 | console.error(error); // eslint-disable-line no-console
60 | }
61 | };
62 |
63 | this.#socket.onerror = (error) => {
64 | console.error(error); // eslint-disable-line no-console
65 | };
66 |
67 | this.#socket.onclose = () => {
68 | if (this.#reconnectionAttempt >= MAX_RECONNECTION) {
69 | return;
70 | }
71 |
72 | this.#reconnectionAttempt += 1;
73 |
74 | setTimeout(() => {
75 | this.#connect();
76 | }, this.#reconnectionAttempt * 500);
77 | };
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/packages/plugin-event-emitter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/plugin-event-emitter",
3 | "version": "0.44.0",
4 | "description": "Merkur event emitter plugin.",
5 | "main": "lib/index",
6 | "module": "lib/index",
7 | "unpkg": "lib/index.umd.js",
8 | "sideEffects": false,
9 | "exports": {
10 | ".": {
11 | "import": "./lib/index.mjs",
12 | "require": "./lib/index.cjs"
13 | },
14 | "./lib/index.es9.mjs": "./lib/index.es9.mjs",
15 | "./lib/index.es9.cjs": "./lib/index.es9.cjs"
16 | },
17 | "browser": {
18 | "./lib/index.js": "./lib/index.js",
19 | "./lib/index.cjs": "./lib/index.cjs",
20 | "./lib/index.mjs": "./lib/index.mjs",
21 | "./lib/index.es9.mjs": "./lib/index.es9.mjs"
22 | },
23 | "scripts": {
24 | "preversion": "npm test",
25 | "test": "jest --no-watchman -c ./jest.config.js",
26 | "test:es:version": "es-check es11 ./lib/index.mjs --module && es-check es9 ./lib/index.es9.mjs --module && es-check es9 ./lib/index.es9.cjs --module",
27 | "build": "rollup -c rollup.config.mjs",
28 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
29 | },
30 | "repository": {
31 | "type": "git",
32 | "url": "git+https://github.com/mjancarik/merkur.git"
33 | },
34 | "keywords": [
35 | "merkur",
36 | "plugin",
37 | "microservices",
38 | "microfrontends"
39 | ],
40 | "author": "Miroslav Jancarik",
41 | "license": "ISC",
42 | "bugs": {
43 | "url": "https://github.com/mjancarik/merkur/issues"
44 | },
45 | "publishConfig": {
46 | "registry": "https://registry.npmjs.org/",
47 | "access": "public"
48 | },
49 | "homepage": "https://merkur.js.org/",
50 | "devDependencies": {
51 | "@merkur/core": "^0.44.0"
52 | },
53 | "peerDependencies": {
54 | "@merkur/core": "*"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/plugin-http-client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/plugin-http-client",
3 | "version": "0.44.0",
4 | "description": "Merkur event emitter plugin.",
5 | "main": "lib/index",
6 | "module": "lib/index",
7 | "unpkg": "lib/index.umd.js",
8 | "sideEffects": false,
9 | "exports": {
10 | ".": {
11 | "import": "./lib/index.mjs",
12 | "require": "./lib/index.cjs"
13 | },
14 | "./lib/index.es9.mjs": "./lib/index.es9.mjs",
15 | "./lib/index.es9.cjs": "./lib/index.es9.cjs"
16 | },
17 | "browser": {
18 | "./lib/index.js": "./lib/index.js",
19 | "./lib/index.cjs": "./lib/index.cjs",
20 | "./lib/index.mjs": "./lib/index.mjs",
21 | "./lib/index.es9.mjs": "./lib/index.es9.mjs"
22 | },
23 | "scripts": {
24 | "preversion": "npm test",
25 | "test": "jest --no-watchman -c ./jest.config.js",
26 | "test:es:version": "es-check es11 ./lib/index.mjs --module && es-check es9 ./lib/index.es9.mjs --module && es-check es9 ./lib/index.es9.cjs --module",
27 | "build": "rollup -c rollup.config.mjs",
28 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
29 | },
30 | "repository": {
31 | "type": "git",
32 | "url": "git+https://github.com/mjancarik/merkur.git"
33 | },
34 | "keywords": [
35 | "merkur",
36 | "plugin",
37 | "microservices",
38 | "microfrontends"
39 | ],
40 | "author": "Miroslav Jancarik",
41 | "license": "ISC",
42 | "bugs": {
43 | "url": "https://github.com/mjancarik/merkur/issues"
44 | },
45 | "publishConfig": {
46 | "registry": "https://registry.npmjs.org/",
47 | "access": "public"
48 | },
49 | "homepage": "https://merkur.js.org/",
50 | "devDependencies": {
51 | "@merkur/core": "^0.44.0"
52 | },
53 | "peerDependencies": {
54 | "@merkur/core": "*"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/packages/tools/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/tools",
3 | "version": "0.44.0",
4 | "description": "Merkur tools.",
5 | "bin": {
6 | "merkur-tools": "./bin/merkurTools.js"
7 | },
8 | "main": "index",
9 | "scripts": {
10 | "test": "echo 'Tests pass.'",
11 | "test:es:version": "echo 'Tests pass.'",
12 | "build": "echo 'Build pass.'",
13 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/mjancarik/merkur.git"
18 | },
19 | "keywords": [
20 | "merkur",
21 | "tools"
22 | ],
23 | "author": "Miroslav Jancarik",
24 | "license": "ISC",
25 | "bugs": {
26 | "url": "https://github.com/mjancarik/merkur/issues"
27 | },
28 | "publishConfig": {
29 | "registry": "https://registry.npmjs.org/",
30 | "access": "public"
31 | },
32 | "homepage": "https://merkur.js.org/",
33 | "dependencies": {
34 | "@babel/core": "7.28.5",
35 | "@babel/eslint-parser": "7.28.5",
36 | "@babel/preset-env": "7.28.5",
37 | "babel-jest": "29.7.0",
38 | "core-js": "3.46.0",
39 | "eslint": "8.57.0",
40 | "eslint-config-last": "0.0.5",
41 | "eslint-config-prettier": "9.1.0",
42 | "eslint-plugin-import": "^2.32.0",
43 | "eslint-plugin-jasmine": "4.2.2",
44 | "eslint-plugin-jest": "28.9.0",
45 | "eslint-plugin-prettier": "5.5.4",
46 | "eslint-plugin-react": "7.37.5",
47 | "eslint-plugin-react-hooks": "^4.6.2",
48 | "find-free-port": "^2.0.0",
49 | "jest": "29.7.0",
50 | "jest-environment-jsdom": "^29.7.0",
51 | "jest-watch-typeahead": "^2.2.2",
52 | "prettier": "3.6.2",
53 | "supertest": "7.1.4",
54 | "ws": "8.18.3",
55 | "yargs": "17.7.2"
56 | },
57 | "peerDependencies": {
58 | "express": "*"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/packages/core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/core",
3 | "version": "0.44.0",
4 | "description": "Merkur is tiny and extensible library for creating front-end microservices.",
5 | "main": "lib/index",
6 | "module": "lib/index",
7 | "types": "./types.d.ts",
8 | "unpkg": "lib/index.umd.js",
9 | "sideEffects": false,
10 | "exports": {
11 | ".": {
12 | "types": "./types.d.ts",
13 | "import": "./lib/index.mjs",
14 | "require": "./lib/index.cjs"
15 | },
16 | "./lib/index.es9.mjs": "./lib/index.es9.mjs",
17 | "./lib/index.es9.cjs": "./lib/index.es9.cjs"
18 | },
19 | "browser": {
20 | "./lib/index.js": "./lib/index.js",
21 | "./lib/index.cjs": "./lib/index.cjs",
22 | "./lib/index.mjs": "./lib/index.mjs",
23 | "./lib/index.es9.mjs": "./lib/index.es9.mjs"
24 | },
25 | "scripts": {
26 | "preversion": "npm test",
27 | "test": "jest --no-watchman -c ./jest.config.js",
28 | "test:es:version": "es-check es11 ./lib/index.mjs --module && es-check es9 ./lib/index.es9.mjs --module && es-check es9 ./lib/index.es9.cjs --module",
29 | "build": "rollup -c rollup.config.mjs",
30 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
31 | },
32 | "repository": {
33 | "type": "git",
34 | "url": "git+https://github.com/mjancarik/merkur.git"
35 | },
36 | "keywords": [
37 | "microservices",
38 | "microfrontends",
39 | "SSR",
40 | "merkur",
41 | "widget",
42 | "react",
43 | "preact",
44 | "svelte"
45 | ],
46 | "author": "Miroslav Jancarik",
47 | "license": "ISC",
48 | "bugs": {
49 | "url": "https://github.com/mjancarik/merkur/issues"
50 | },
51 | "publishConfig": {
52 | "registry": "https://registry.npmjs.org/",
53 | "access": "public"
54 | },
55 | "homepage": "https://merkur.js.org/"
56 | }
57 |
--------------------------------------------------------------------------------
/packages/preact/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/preact",
3 | "version": "0.44.0",
4 | "description": "Collection of helpers to aid with Preact integration to @merkur",
5 | "scripts": {
6 | "test": "echo 'Tests pass.'",
7 | "test:es:version": "echo 'Tests pass.'",
8 | "build": "rollup -c rollup.config.mjs",
9 | "dev": "rollup -c rollup.config.mjs -w",
10 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
11 | },
12 | "exports": {
13 | "./entries/client.js": "./entries/client.js",
14 | "./entries/server.js": "./entries/server.js",
15 | "./webpack": "./webpack/index.js",
16 | "./cli": "./cli/index.mjs",
17 | "./client": {
18 | "types": "./lib/client/client.d.ts",
19 | "import": "./lib/client/client.mjs",
20 | "require": "./lib/client/client.cjs"
21 | },
22 | "./server": {
23 | "types": "./lib/server/server.d.ts",
24 | "import": "./lib/server/server.mjs",
25 | "require": "./lib/server/server.cjs"
26 | }
27 | },
28 | "keywords": [
29 | "merkur",
30 | "preact",
31 | "micro",
32 | "frontend"
33 | ],
34 | "repository": {
35 | "type": "git",
36 | "url": "git+https://github.com/mjancarik/merkur.git"
37 | },
38 | "author": "Jan Šimeček",
39 | "license": "ISC",
40 | "bugs": {
41 | "url": "https://github.com/mjancarik/merkur/issues"
42 | },
43 | "publishConfig": {
44 | "registry": "https://registry.npmjs.org/",
45 | "access": "public"
46 | },
47 | "dependencies": {
48 | "@babel/preset-react": "^7.28.5",
49 | "preact": "^10.27.2",
50 | "preact-render-to-string": "^6.6.3"
51 | },
52 | "peerDependencies": {
53 | "@merkur/core": ">=0.34",
54 | "@merkur/plugin-component": ">=0.34",
55 | "@merkur/tool-webpack": ">=0.28",
56 | "babel-loader": ">=9"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/packages/tool-storybook/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@merkur/tool-storybook",
3 | "version": "0.44.0",
4 | "description": "Merkur integration to storybook tool.",
5 | "main": "lib/index",
6 | "module": "lib/index",
7 | "sideEffects": false,
8 | "exports": {
9 | ".": {
10 | "import": "./lib/index.mjs",
11 | "require": "./lib/index.cjs"
12 | },
13 | "./lib/index.es9.mjs": "./lib/index.es9.mjs",
14 | "./lib/index.es9.cjs": "./lib/index.es9.cjs"
15 | },
16 | "browser": {
17 | "./lib/index.js": "./lib/index.js",
18 | "./lib/index.cjs": "./lib/index.cjs",
19 | "./lib/index.mjs": "./lib/index.mjs",
20 | "./lib/index.es9.mjs": "./lib/index.es9.mjs"
21 | },
22 | "scripts": {
23 | "preversion": "npm test",
24 | "test": "jest --no-watchman -c ./jest.config.js",
25 | "test:es:version": "es-check es11 ./lib/index.mjs --module && es-check es9 ./lib/index.es9.mjs --module && es-check es9 ./lib/index.es9.cjs --module",
26 | "build": "rollup -c rollup.config.mjs",
27 | "postpublish": "node ../../utils/restoreLatestTag.mjs"
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "git+https://github.com/mjancarik/merkur.git"
32 | },
33 | "keywords": [
34 | "merkur",
35 | "tool",
36 | "storybook"
37 | ],
38 | "author": "Miroslav Jancarik",
39 | "license": "ISC",
40 | "bugs": {
41 | "url": "https://github.com/mjancarik/merkur/issues"
42 | },
43 | "publishConfig": {
44 | "registry": "https://registry.npmjs.org/",
45 | "access": "public"
46 | },
47 | "homepage": "https://merkur.js.org/",
48 | "devDependencies": {
49 | "@merkur/core": "^0.44.0",
50 | "@merkur/plugin-component": "^0.44.0"
51 | },
52 | "peerDependencies": {
53 | "@merkur/core": "*",
54 | "@merkur/plugin-component": "*"
55 | }
56 | }
57 |
--------------------------------------------------------------------------------