diff --git a/packages/shin/build.js b/packages/shin/build.js
new file mode 100644
index 00000000000..543259e899a
--- /dev/null
+++ b/packages/shin/build.js
@@ -0,0 +1,43 @@
+/* This script will build the package with esbuild */
+const esbuild = require('esbuild')
+const pkg = require('./package.json')
+
+// Create banner based on package info
+const banner = `/**
+ * ${pkg.name} | v${pkg.version}
+ * ${pkg.description}
+ * (c) ${new Date().getFullYear()} ${pkg.author}
+ * @license ${pkg.license}
+ */`
+
+// Shared esbuild options
+const options = {
+ banner: { js: banner },
+ bundle: true,
+ entryPoints: ['src/index.js'],
+ external: ["@freesewing"],
+ metafile: process.env.VERBOSE ? true : false,
+ minify: process.env.NO_MINIFY ? false : true,
+ sourcemap: true,
+}
+
+// Different formats
+const formats = {
+ cjs: "dist/index.js",
+ esm: "dist/index.mjs",
+}
+
+// Let esbuild generate different formats
+let result
+(async () => {
+ for (const [format, outfile] of Object.entries(formats)) {
+ result = await esbuild
+ .build({ ...options, outfile, format })
+ .catch(() => process.exit(1))
+ }
+
+ if (process.env.VERBOSE) {
+ const info = await esbuild.analyzeMetafile(result.metafile)
+ console.log(info)
+ }
+})()
diff --git a/packages/shin/config/index.js b/packages/shin/config/index.js
index 61ecd72231b..6fc17724ab6 100644
--- a/packages/shin/config/index.js
+++ b/packages/shin/config/index.js
@@ -1,11 +1,11 @@
-import pkg from '../package.json'
-import { elastics } from '@freesewing/snapseries'
+import { version } from '../package.json'
import freesewing from '@freesewing/core'
-const { pctBasedOn } = freesewing
+import configHelpers from '@freesewing/config-helpers'
+const { elastics, pctBasedOn } = configHelpers
export default {
+ version,
name: 'shin',
- version: pkg.version,
design: 'Joost De Cock',
code: 'Joost De Cock',
department: 'swimwear',
diff --git a/packages/shin/example/.babelrc b/packages/shin/example/.babelrc
deleted file mode 100644
index 6e3090a4956..00000000000
--- a/packages/shin/example/.babelrc
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "plugins": [
- ["prismjs", {
- "languages": ["javascript", "css", "markup"],
- "plugins": ["line-numbers"],
- "theme": "twilight",
- "css": true
- }]
- ]
-}
diff --git a/packages/shin/example/.netlify/state.json b/packages/shin/example/.netlify/state.json
deleted file mode 100644
index a19a2cb1794..00000000000
--- a/packages/shin/example/.netlify/state.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "siteId": "e3da2000-0af2-4240-9d9f-b5a2ea509485"
-}
\ No newline at end of file
diff --git a/packages/shin/example/README.md b/packages/shin/example/README.md
deleted file mode 100644
index 85377527667..00000000000
--- a/packages/shin/example/README.md
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-
-FreeSewing v2
-
-A JavaScript library for made-to-measure sewing patterns
-
-
-
-
-
-
-
-# shin example
-
-This project was bootstrapped with [Create Freesewing Pattern](https://en.freesewing.dev/create-freesewing-pattern):
-
-```js
-npm init freesewing-pattern
-```
-
-This example folder is part of the local development environment.
-It is **not** part of the pattern's source code.
-
-To run this example, follow these steps:
-
- - In the folder above this one, run: `yarn start` (or `npm start`)
- - Then, in new terminal, run the same command in this folder: `yarn start` (or `npm start`)
-
-This will spin up the development environment, similar to [our online demo](https://shin.freesewing.dev/).
-
-## About FreeSewing 🤔
-
-Where the world of makers and developers collide, that's where you'll find FreeSewing.
-
-Our [core library](https://freesewing.dev/en/freesewing) is a *batteries-included* toolbox
-for parametric design of sewing patterns. It's a modular system (check our list
-of [plugins](https://freesewing.dev/en/plugins) and getting started is as simple as:
-
-```bash
-npm init freesewing-pattern
-```
-
-The [getting started] section on [freesewing.dev](https://freesewing.dev/) is a good
-entrypoint to our documentation, but you'll find a lot more there, including
-our [API documentation](https://freesewing.dev/en/freesewing/api),
-as well as [examples](https://freesewing.dev/en/freesewing/examples),
-and [best practices](https://freesewing.dev/en/do).
-
-If you're a maker, checkout [freesewing.org](https://freesewing/) where you can generate
-our sewing patterns adapted to your measurements.
-
-## Support FreeSewing: Become a patron 🥰
-
-FreeSewing is an open source project run by a community,
-and financially supported by our patrons.
-
-If you feel what we do is worthwhile, you too
-should [become a patron](https://freesewing.org/patrons/join).
-
-## Links 👩💻
-
- - 💻 Makers website: [freesewing.org](https://freesewing.org)
- - 💻 Developers website: [freesewing.dev](https://freesewing.org)
- - 💬 Chat: [gitter.im/freesewing](https://gitter.im/freesewing/freesewing)
- - 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
- - 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
-
-## License: MIT 🤓
-
-© [Joost De Cock](https://github.com/joostdecock).
-See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
-
-## Where to get help 🤯
-
-Our [chatroom on Gitter](https://gitter.im) is the best place to ask questions,
-share your feedback, or just hang out.
-
-If you want to report a problem, please [create an issue](https://github.com/freesewing/freesewing/issues/new).
-
diff --git a/packages/shin/example/netlify.toml b/packages/shin/example/netlify.toml
deleted file mode 100644
index b596045e4e9..00000000000
--- a/packages/shin/example/netlify.toml
+++ /dev/null
@@ -1,9 +0,0 @@
-[build]
- base = "packages/shin/example"
- publish = "build"
- command = "npm run build"
-
-[[redirects]]
- from = "/*"
- to = "/index.html"
- status = 200
diff --git a/packages/shin/example/package.json b/packages/shin/example/package.json
deleted file mode 100644
index ee62d74d4b0..00000000000
--- a/packages/shin/example/package.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "name": "shin",
- "homepage": "https://shin.freesewing.dev/",
- "version": "",
- "private": true,
- "dependencies": {
- "@fontsource/permanent-marker": "latest",
- "@fontsource/roboto-mono": "latest",
- "@fontsource/ubuntu": "latest",
- "@freesewing/components": "latest",
- "@freesewing/core": "latest",
- "@freesewing/css-theme": "latest",
- "@freesewing/i18n": "latest",
- "@freesewing/models": "latest",
- "@freesewing/mui-theme": "latest",
- "@freesewing/pattern-info": "latest",
- "@freesewing/plugin-bundle": "latest",
- "@freesewing/plugin-theme": "latest",
- "@freesewing/plugin-i18n": "latest",
- "@freesewing/plugin-svgattr": "latest",
- "@freesewing/utils": "latest",
- "@material-ui/core": "^4.11.4",
- "@material-ui/icons": "^4.11.2",
- "@material-ui/lab": "^v4.0.0-alpha.57",
- "prismjs": "1.25.0",
- "react": "^17.0.2",
- "react-dom": "^17.0.2",
- "react-intl": "^5.18.0",
- "react-scripts": "^4.0.3",
- "react-error-overlay": "6.0.9",
- "file-saver": "^2.0.5",
- "react-markdown": "6.0.2",
- "source-map-explorer": "^2.5.2"
- },
- "scripts": {
- "analyze": "source-map-explorer 'build/static/js/*.js'",
- "size": "source-map-explorer 'build/static/js/*.js' --tsv --no-root",
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
- "eject": "react-scripts eject"
- },
- "eslintConfig": {
- "extends": "react-app"
- },
- "browserslist": [
- "defaults"
- ],
- "devDependencies": {
- "babel-plugin-prismjs": "2.0.1",
- "react-error-overlay": "6.0.9"
- },
- "resolutions": {
- "react-error-overlay": "6.0.9"
- }
-}
diff --git a/packages/shin/example/public/App.js b/packages/shin/example/public/App.js
deleted file mode 100644
index 89c6ad6081f..00000000000
--- a/packages/shin/example/public/App.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from "react";
-import freesewing from "@freesewing/core";
-import { Workbench } from "@freesewing/components";
-import "typeface-roboto-condensed";
-import "@freesewing/css-theme";
-import "./App.css";
-
-import Pattern from "pattern";
-
-const App = props => {
- let instance = new Pattern();
- let config = instance.config;
- return (
-
- );
-};
-
-export default App;
diff --git a/packages/shin/example/public/favicon.ico b/packages/shin/example/public/favicon.ico
deleted file mode 100644
index 95061a260f1..00000000000
Binary files a/packages/shin/example/public/favicon.ico and /dev/null differ
diff --git a/packages/shin/example/public/index.html b/packages/shin/example/public/index.html
deleted file mode 100644
index 4a7e825e868..00000000000
--- a/packages/shin/example/public/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- shin
-
-
-
-
-
-
-
diff --git a/packages/shin/example/public/layout.css b/packages/shin/example/public/layout.css
deleted file mode 100644
index c62502f9791..00000000000
--- a/packages/shin/example/public/layout.css
+++ /dev/null
@@ -1 +0,0 @@
-div.layout-wrapper{width:100%;margin:0;padding:0;background-color:red;background:#f8f9fa;background:linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%)}div.layout-wrapper div.layout{display:flex;max-width:1600px;margin:auto;padding:0;flex-direction:row;flex-wrap:nowrap;justify-content:space-between;background-color:#f8f9fa;min-height:calc(100vh - 64px)}div.layout-wrapper div.layout>aside{width:33%;background:#f1f3f5;border-right:2px solid #dee2e6}div.layout-wrapper div.layout>section{margin:0;padding:1rem}div.layout-wrapper div.layout>section>div.content{max-width:66ch;min-width:340px}div.layout-wrapper div.layout>section>div.content.wide{max-width:100%;margin:auto}.theme-wrapper.dark header{background-color:#1a1d21}.theme-wrapper.dark div.layout-wrapper{background:#f8f9fa;background:linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%)}.theme-wrapper.dark div.layout-wrapper div.layout{background-color:#212529}.theme-wrapper.dark div.layout-wrapper div.layout>aside{background-color:#1a1d21;border-right:2px solid #343a40}header a svg{color:#ced4da}header a:first-of-type svg{color:#f8f9fa}header a:hover svg{color:#b197fc}header a span,header button span{color:#ced4da}header a span svg,header button span svg{color:#dee2e6}header a:hover span,header button:hover span{color:#f8f9fa}header a:hover span svg,header button:hover span svg{color:#b197fc}header a,header button{padding:0 1vw !important}@media (min-width: 1200px){div.layout>section{width:63%}}@media (max-width: 1199px) and (min-width: 960px){div.layout>aside{width:298px}div.layout>section{width:calc(100% - 300px - 4rem);max-width:none;margin:0 1rem 0 3rem}}@media (max-width: 959px){div.layout>aside{width:218px}div.layout>section{width:calc(100% - 220px - 4rem);max-width:none;margin:0;padding:0 2rem}div.layout>section div.content{min-width:inherit}}@media (max-width: 599px){div.layout>aside{display:none}div.layout>section{width:calc(100%);margin:0 auto;padding:0 1.5rem;max-width:none}}div.gatsby-highlight{margin-bottom:1rem}@media (max-width: 599px){#mobile-menu{position:fixed;top:0;left:0;width:100%;height:100vh;padding:0 0 1rem;max-width:600px;z-index:-10;transition:opacity 0.25s ease 0s;opacity:0;overflow:scroll}#mobile-menu>ul,#mobile-menu>div{transform:translate(0px, 10px);transition:transform 0.25s ease 0s}.theme-wrapper.show-menu #mobile-menu{opacity:1;z-index:10}.theme-wrapper.show-menu #mobile-menu>div{transform:translate(0px, 0px)}}.theme-wrapper.light div.draft-ui-menu,.theme-wrapper.light div.menu{background:#f1f3f5}.theme-wrapper.dark div.draft-ui-menu,.theme-wrapper.dark div.menu{background:#343a40}.theme-wrapper.show-menu div.menu{opacity:1;z-index:10}.theme-wrapper.show-menu div.menu>div{transform:translate(0px, 0px)}div.spaced-buttons>button{margin:0 0.5rem 0.5rem 0}div.spaced>*{margin:0 0.5rem 0.5rem 0}ul#pre-main-menu{margin:0;padding:0}.boldish{font-weight:500}.freesewing.draft{padding:1rem}li.action{clear:both}li.action span.MuiSwitch-root{float:right}.theme-wrapper.light ul#draft-config li.action.toggle.off,.theme-wrapper.dark ul#draft-config li.action.toggle.off{color:#868e96}.theme-wrapper.light ul#draft-config li.action.toggle.off>span svg,.theme-wrapper.dark ul#draft-config li.action.toggle.off>span svg{color:#868e96}footer{background-color:#1a1d21;color:#adb5bd;padding:3rem 0 6rem}footer a{color:#dee2e6 !important;font-weight:400}footer a:hover{color:#d0bfff !important}footer div.cols{display:flex;flex-direction:row;justify-content:space-between;max-width:1600px;margin:auto;padding:0 1.5rem}footer div.cols>div{min-width:150px;max-width:calc(20% - 4rem);padding:0 2rem 0 0;width:100%}footer ul{text-align:left;font-size:1.1rem;margin:0;padding:0;width:100%}footer ul li:first-of-type{padding:0.35rem 0.75rem}footer ul li{display:block}footer ul li a:hover{text-decoration:none !important}footer ul li.heading{font-weight:bold;border-bottom:3px solid #adb5bd;margin-bottom:0.5rem}@media (min-width: 1200px){footer div.cols>div:last-of-type{min-width:350px}}@media (min-width: 600px) and (max-width: 959px){footer div.cols{flex-wrap:wrap}footer div.cols>div{width:calc(30% - 4rem);padding:0 1rem}}@media (max-width: 599px){footer div.cols{display:block}footer div.cols>div{margin:2rem auto 0;max-width:calc(100% - 4rem)}footer div.cols>div:first-of-type{margin-top:0}}
diff --git a/packages/shin/example/public/manifest.json b/packages/shin/example/public/manifest.json
deleted file mode 100644
index 3cc3c72948c..00000000000
--- a/packages/shin/example/public/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "short_name": "shin",
- "name": "shin",
- "icons": [
- {
- "src": "favicon.ico",
- "sizes": "64x64 32x32 24x24 16x16",
- "type": "image/x-icon"
- }
- ],
- "start_url": ".",
- "display": "standalone",
- "theme_color": "#000000",
- "background_color": "#ffffff"
-}
diff --git a/packages/shin/example/src/App.js b/packages/shin/example/src/App.js
deleted file mode 100644
index 7bb0f0e7112..00000000000
--- a/packages/shin/example/src/App.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from 'react'
-import freesewing from '@freesewing/core'
-import Workbench from '@freesewing/components/Workbench'
-import '@freesewing/css-theme'
-import Pattern from './pattern/src/index.js'
-/*
- * The following symlink is required to make this import work:
- * `root_folder/example/src/pattern => `../../`
- *
- * Without it, we can't import the pattern as a local file
- * since create-react-app does not allow imports outside ./src
- * If it's imported as a dependency, webpack will cache the
- * build and there will be no hot-reloading of changes
- */
-
-const App = (props) => {
- // You can use this to add translations
- /*
- let translations = {
- JSON: 'JSON',
- someOtherString: 'Some other string that needs translation'
- }
- */
-
- // Adds support for loading an external pattern configuration
- let recreate = false
- if (window) recreate = window.location.pathname.substr(1).split('/')
- if (recreate.length === 3 && recreate[0] === 'recreate') {
- recreate = { from: recreate[1], id: recreate[2] }
- } else {
- recreate = false
- }
-
- return (
-
- )
-}
-
-export default App
diff --git a/packages/shin/example/src/index.js b/packages/shin/example/src/index.js
deleted file mode 100644
index 24aefad45a1..00000000000
--- a/packages/shin/example/src/index.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-import App from './App'
-import * as serviceWorker from './serviceWorker'
-import './layout.css'
-
-ReactDOM.render(, document.getElementById('root'))
-
-// If you want your app to work offline and load faster, you can change
-// unregister() to register() below. Note this comes with some pitfalls.
-// Learn more about service workers: http://bit.ly/CRA-PWA
-serviceWorker.unregister()
diff --git a/packages/shin/example/src/layout.css b/packages/shin/example/src/layout.css
deleted file mode 100644
index a4963e16e55..00000000000
--- a/packages/shin/example/src/layout.css
+++ /dev/null
@@ -1,273 +0,0 @@
-* {
- box-sizing: border-box;
-}
-.MuiToolbar-root {
- overflow-y: auto;
-}
-div.layout-wrapper {
- width: 100%;
- margin: 0;
- padding: 0;
- background: #f8f9fa;
- background: linear-gradient(90deg, #f1f3f5 0%, #f1f3f5 25%, #f8f9fa 26%, #f8f9fa 100%);
-}
-div.layout-wrapper div.layout {
- display: flex;
- max-width: 1600px;
- margin: auto;
- padding: 0;
- flex-direction: row;
- flex-wrap: nowrap;
- justify-content: space-between;
- background-color: #f8f9fa;
- min-height: calc(100vh - 64px);
-}
-div.layout-wrapper div.layout > aside {
- width: 33%;
- background: #f1f3f5;
- border-right: 2px solid #dee2e6;
-}
-div.layout-wrapper div.layout > section {
- margin: 0;
- padding: 1rem;
-}
-div.layout-wrapper div.layout > section > div.content {
- max-width: 66ch;
- min-width: 340px;
-}
-div.layout-wrapper div.layout > section > div.content.wide {
- max-width: 100%;
- margin: auto;
-}
-
-.theme-wrapper.dark header {
- background-color: #1a1d21;
-}
-
-.theme-wrapper.dark div.layout-wrapper {
- background: #f8f9fa;
- background: linear-gradient(90deg, #1a1d21 0%, #1a1d21 25%, #212529 26%, #212529 100%);
-}
-.theme-wrapper.dark div.layout-wrapper div.layout {
- background-color: #212529;
-}
-.theme-wrapper.dark div.layout-wrapper div.layout > aside {
- background-color: #1a1d21;
- border-right: 2px solid #343a40;
-}
-
-/* monitor */
-@media (min-width: 1200px) {
- div.layout > section {
- width: 63%;
- }
-}
-
-/* slate */
-@media (max-width: 1199px) and (min-width: 960px) {
- div.layout > aside {
- width: 298px;
- }
- div.layout > section {
- width: calc(100% - 300px - 4rem);
- max-width: none;
- margin: 0 1rem 0 3rem;
- }
-}
-
-/* tablet */
-@media (max-width: 959px) {
- div.layout > aside {
- width: 218px;
- }
- div.layout > section {
- width: calc(100% - 220px - 4rem);
- max-width: none;
- margin: 0;
- padding: 0 2rem;
- }
- div.layout > section div.content {
- min-width: inherit;
- }
-}
-
-/* mobile */
-@media (max-width: 599px) {
- div.layout > aside {
- display: none;
- }
- div.layout > section {
- width: calc(100%);
- margin: 0 auto;
- padding: 0 1.5rem;
- max-width: none;
- }
-}
-
-div.gatsby-highlight {
- margin-bottom: 1rem;
-}
-
-@media (max-width: 599px) {
- #mobile-menu {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100vh;
- padding: 0 0 1rem;
- max-width: 600px;
- z-index: -10;
- transition: opacity 0.25s ease 0s;
- opacity: 0;
- overflow: scroll;
- }
- #mobile-menu > ul,
- #mobile-menu > div {
- transform: translate(0px, 10px);
- transition: transform 0.25s ease 0s;
- }
- .theme-wrapper.show-menu #mobile-menu {
- opacity: 1;
- z-index: 10;
- }
- .theme-wrapper.show-menu #mobile-menu > div {
- transform: translate(0px, 0px);
- }
-}
-
-.theme-wrapper.light div.draft-ui-menu,
-.theme-wrapper.light div.menu {
- background: #f1f3f5;
-}
-
-.theme-wrapper.dark div.draft-ui-menu,
-.theme-wrapper.dark div.menu {
- background: #343a40;
-}
-
-.theme-wrapper.show-menu div.menu {
- opacity: 1;
- z-index: 10;
-}
-.theme-wrapper.show-menu div.menu > div {
- transform: translate(0px, 0px);
-}
-
-div.spaced-buttons > button {
- margin: 0 0.5rem 0.5rem 0;
-}
-
-div.spaced > * {
- margin: 0 0.5rem 0.5rem 0;
-}
-
-ul#pre-main-menu {
- margin: 0;
- padding: 0;
-}
-
-.boldish {
- font-weight: 500;
-}
-
-.freesewing.draft {
- padding: 1rem;
-}
-
-li.action {
- clear: both;
-}
-
-li.action span.MuiSwitch-root {
- float: right;
-}
-
-.theme-wrapper.light ul#draft-config li.action.toggle.off,
-.theme-wrapper.dark ul#draft-config li.action.toggle.off {
- color: #868e96;
-}
-.theme-wrapper.light ul#draft-config li.action.toggle.off > span svg,
-.theme-wrapper.dark ul#draft-config li.action.toggle.off > span svg {
- color: #868e96;
-}
-
-footer {
- background-color: #1a1d21;
- color: #adb5bd;
- padding: 3rem 0 6rem;
-}
-footer a {
- color: #dee2e6 !important;
- font-weight: 400;
-}
-footer a:hover {
- color: #d0bfff !important;
-}
-footer div.cols {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- max-width: 1600px;
- margin: auto;
- padding: 0 1.5rem;
-}
-footer div.cols > div {
- min-width: 150px;
- max-width: calc(20% - 4rem);
- padding: 0 2rem 0 0;
- width: 100%;
-}
-footer ul {
- text-align: left;
- font-size: 1.1rem;
- margin: 0;
- padding: 0;
- width: 100%;
-}
-footer ul li:first-of-type {
- padding: 0.35rem 0.75rem;
-}
-footer ul li {
- display: block;
-}
-footer ul li a:hover {
- text-decoration: none !important;
-}
-footer ul li.heading {
- font-weight: bold;
- border-bottom: 3px solid #adb5bd;
- margin-bottom: 0.5rem;
-}
-
-/* XL screens */
-@media (min-width: 1200px) {
- footer div.cols > div:last-of-type {
- min-width: 350px;
- }
-}
-
-/* SM screens */
-@media (min-width: 600px) and (max-width: 959px) {
- footer div.cols {
- flex-wrap: wrap;
- }
- footer div.cols > div {
- width: calc(30% - 4rem);
- padding: 0 1rem;
- }
-}
-
-/* XS screens */
-@media (max-width: 599px) {
- footer div.cols {
- display: block;
- }
- footer div.cols > div {
- margin: 2rem auto 0;
- max-width: calc(100% - 4rem);
- }
- footer div.cols > div:first-of-type {
- margin-top: 0;
- }
-}
diff --git a/packages/shin/example/src/pattern b/packages/shin/example/src/pattern
deleted file mode 120000
index 6581736d623..00000000000
--- a/packages/shin/example/src/pattern
+++ /dev/null
@@ -1 +0,0 @@
-../../
\ No newline at end of file
diff --git a/packages/shin/example/src/serviceWorker.js b/packages/shin/example/src/serviceWorker.js
deleted file mode 100644
index 4fe923e7795..00000000000
--- a/packages/shin/example/src/serviceWorker.js
+++ /dev/null
@@ -1,123 +0,0 @@
-// In production, we register a service worker to serve assets from local cache.
-
-// This lets the app load faster on subsequent visits in production, and gives
-// it offline capabilities. However, it also means that developers (and users)
-// will only see deployed updates on the "N+1" visit to a page, since previously
-// cached resources are updated in the background.
-
-// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
-// This link also includes instructions on opting out of this behavior.
-
-const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.1/8 is considered localhost for IPv4.
- window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
-)
-
-export function register(config) {
- if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
- // The URL constructor is available in all browsers that support SW.
- const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
- if (publicUrl.origin !== window.location.origin) {
- // Our service worker won't work if PUBLIC_URL is on a different origin
- // from what our page is served on. This might happen if a CDN is used to
- // serve assets; see https://github.com/facebook/create-react-app/issues/2374
- return
- }
-
- window.addEventListener('load', () => {
- const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
-
- if (isLocalhost) {
- // This is running on localhost. Let's check if a service worker still exists or not.
- checkValidServiceWorker(swUrl, config)
-
- // Add some additional logging to localhost, pointing developers to the
- // service worker/PWA documentation.
- navigator.serviceWorker.ready.then(() => {
- console.log(
- 'This web app is being served cache-first by a service ' +
- 'worker. To learn more, visit https://goo.gl/SC7cgQ'
- )
- })
- } else {
- // Is not local host. Just register service worker
- registerValidSW(swUrl, config)
- }
- })
- }
-}
-
-function registerValidSW(swUrl, config) {
- navigator.serviceWorker
- .register(swUrl)
- .then((registration) => {
- registration.onupdatefound = () => {
- const installingWorker = registration.installing
- installingWorker.onstatechange = () => {
- if (installingWorker.state === 'installed') {
- if (navigator.serviceWorker.controller) {
- // At this point, the old content will have been purged and
- // the fresh content will have been added to the cache.
- // It's the perfect time to display a "New content is
- // available; please refresh." message in your web app.
- console.log('New content is available; please refresh.')
-
- // Execute callback
- if (config.onUpdate) {
- config.onUpdate(registration)
- }
- } else {
- // At this point, everything has been precached.
- // It's the perfect time to display a
- // "Content is cached for offline use." message.
- console.log('Content is cached for offline use.')
-
- // Execute callback
- if (config.onSuccess) {
- config.onSuccess(registration)
- }
- }
- }
- }
- }
- })
- .catch((error) => {
- console.error('Error during service worker registration:', error)
- })
-}
-
-function checkValidServiceWorker(swUrl, config) {
- // Check if the service worker can be found. If it can't reload the page.
- fetch(swUrl)
- .then((response) => {
- // Ensure service worker exists, and that we really are getting a JS file.
- if (
- response.status === 404 ||
- response.headers.get('content-type').indexOf('javascript') === -1
- ) {
- // No service worker found. Probably a different app. Reload the page.
- navigator.serviceWorker.ready.then((registration) => {
- registration.unregister().then(() => {
- window.location.reload()
- })
- })
- } else {
- // Service worker found. Proceed as normal.
- registerValidSW(swUrl, config)
- }
- })
- .catch(() => {
- console.log('No internet connection found. App is running in offline mode.')
- })
-}
-
-export function unregister() {
- if ('serviceWorker' in navigator) {
- navigator.serviceWorker.ready.then((registration) => {
- registration.unregister()
- })
- }
-}
diff --git a/packages/shin/package.json b/packages/shin/package.json
index bed393685ee..cff4d46c8ae 100644
--- a/packages/shin/package.json
+++ b/packages/shin/package.json
@@ -28,20 +28,19 @@
"module": "dist/index.mjs",
"scripts": {
"clean": "rimraf dist",
- "build": "rollup -c",
- "cibuild_step1": "rollup -c",
+ "build": "node build.js",
+ "mbuild": "NO_MINIFY=1 node build.js",
+ "vbuild": "VERBOSE=1 node build.js",
+ "cibuild_step1": "node build.js",
"test": "BABEL_ENV=production npx mocha tests/*.test.mjs --require @babel/register",
- "pubtest": "npm publish --registry http://localhost:6662",
- "pubforce": "npm publish",
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
- "start": "rollup -c -w",
- "netlify": "echo \"Not configured yet\"",
- "testci": "BABEL_ENV=production npx mocha tests/*.test.mjs --require @babel/register --reporter ../../tests/reporters/terse.js"
+ "testci": "BABEL_ENV=production npx mocha tests/*.test.mjs --require @babel/register --reporter ../../tests/reporters/terse.js",
+ "prettier": "npx prettier --write 'src/*.js' 'config/*.js'"
},
"peerDependencies": {
"@freesewing/core": "^2.20.8",
"@freesewing/plugin-bundle": "^2.20.8",
- "@freesewing/snapseries": "^2.20.8"
+ "@freesewing/config-helpers": "^2.20.8"
},
"dependencies": {},
"devDependencies": {
@@ -58,12 +57,6 @@
"@freesewing/utils": "^2.20.8",
"react-scripts": "^5.0.0",
"webpack": "^5.67.0",
- "rollup": "^2.66.1",
- "@rollup/plugin-babel": "^5.3.0",
- "@rollup/plugin-commonjs": "^21.0.1",
- "@rollup/plugin-json": "^4.1.0",
- "@rollup/plugin-node-resolve": "^13.1.3",
- "rollup-plugin-peer-deps-external": "^2.2.4",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^v4.0.0-alpha.60",
@@ -84,10 +77,7 @@
"tag": "latest"
},
"engines": {
- "node": ">=12.0.0",
+ "node": ">=14.0.0",
"npm": ">=6"
- },
- "rollup": {
- "exports": "default"
}
}
diff --git a/packages/shin/rollup.config.js b/packages/shin/rollup.config.js
deleted file mode 100644
index 83bc5ef0eec..00000000000
--- a/packages/shin/rollup.config.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import resolve from '@rollup/plugin-node-resolve'
-import commonjs from '@rollup/plugin-commonjs'
-import json from '@rollup/plugin-json'
-import peerDepsExternal from 'rollup-plugin-peer-deps-external'
-import { name, version, description, author, license, main, module, rollup } from './package.json'
-
-const banner = `/**\n * ${name} | v${version}\n * ${description}\n * (c) ${new Date().getFullYear()} ${author}\n * @license ${license}\n */`
-const output = [
- {
- banner,
- file: main,
- format: 'cjs',
- sourcemap: true,
- exports: rollup.exports,
- },
-]
-if (typeof module !== 'undefined')
- output.push({
- banner,
- file: module,
- format: 'es',
- sourcemap: true,
- })
-
-export default {
- input: 'src/index.js',
- output,
- plugins: [peerDepsExternal(), resolve({ modulesOnly: true }), commonjs(), json()],
-}
diff --git a/packages/shin/src/index.js b/packages/shin/src/index.js
index fceb69babc5..d559d65b813 100644
--- a/packages/shin/src/index.js
+++ b/packages/shin/src/index.js
@@ -7,11 +7,15 @@ import draftFront from './front'
import draftWaistband from './waistband'
// Create new design
-const Pattern = new freesewing.Design(config, plugins)
+const Shin = new freesewing.Design(config, plugins)
// Attach draft methods to prototype
-Pattern.prototype.draftBack = draftBack
-Pattern.prototype.draftFront = draftFront
-Pattern.prototype.draftWaistband = draftWaistband
+Shin.prototype.draftBack = draftBack
+Shin.prototype.draftFront = draftFront
+Shin.prototype.draftWaistband = draftWaistband
-export default Pattern
+// Named exports
+export { config, Shin }
+
+// Default export
+export default Shin