Skip to content

Commit

Permalink
feat: initial check-in store package
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Apr 7, 2020
1 parent 789da10 commit 69f5762
Show file tree
Hide file tree
Showing 31 changed files with 585 additions and 298 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,28 @@

# Motivation

The `component-controls` package aims to facilitate designing, developing and testing of components
The `component-controls` package aims to facilitate designing, developing and testing of components.

-

# Inspiration

> If I have seen further than others, it is by standing upon the shoulders of giants.

There are many developments that have contribiuted to the creation of `component-controls`, and here we will list but a few of them:

- [storybook](https://storybook.js.org) is the original system that helps teams to design, develop and test components. The strong support for testing and the creation of an open [Component Story Format](https://github.com/storybookjs/csf) were an inspiration, as well as the [Storybook Addon Knobs](https://github.com/storybookjs/storybook/tree/next/addons/knobs) for providing configurable component properties.

- [docz](https://www.docz.site) has a beautiful architecture and introduced open [gatsby](https://www.gatsbyjs.org) builds. This monorepo was heavily influenced by the `docz` project structure.

- [abstract syntax tree (AST)](https://en.wikipedia.org/wiki/Abstract_syntax_tree) advancements have been greatly responsible for making possible the parsing and analysis features of this library.

- [blocks-ui](https://blocks-ui.com) is taking `AST` to a new level by generating and reverse-sing AST to create [react](https://reactjs.org) applications and has been an inspiraton for pushing the enveloppe on our own `AST` work.

- [theme-ui](https://theme-ui.com) is the driving force for standardizing `react` theming and design systems. `theme-ui` is used by our project as the theming and components founding block.


# Core packages

<package-section file="./core/specification/README.md" section="overview" />
Expand Down
2 changes: 0 additions & 2 deletions core/loader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
"@component-controls/specification": "^0.6.0",
"@storybook/csf": "^0.0.1",
"crypto": "^1.0.1",
"deepmerge": "^4.2.2",
"js-string-escape": "^1.0.1",
"loader-utils": "^1.2.3",
"typescript": "^3.8.3",
Expand All @@ -45,7 +44,6 @@
"devDependencies": {
"@types/jest": "^25.1.2",
"@types/loader-utils": "^1.1.3",
"@types/webpack-env": "^1.15.1",
"cross-env": "^5.2.1",
"eslint": "^6.5.1",
"jest": "^24.9.0"
Expand Down
1 change: 1 addition & 0 deletions core/loader/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class StoriesInjectPlugin {
const source = compilation.assets[file];
const placeholderPos = source.source().indexOf(placeholder);
if (placeholderPos > -1) {
store.hash = this.compilationHash;
const newContent = jsStringEscape(JSON.stringify(store));
const source = compilation.assets[file];
const newSource = new ReplaceSource(source, file);
Expand Down
12 changes: 10 additions & 2 deletions core/loader/src/store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { StoriesStore } from '@component-controls/specification';

export const store: StoriesStore[] = [];
export const store: {
/**
* unique has for a store
*/
hash?: string;
stores: StoriesStore[];
} = {
stores: [],
};

export const addStoriesKind = async (added: StoriesStore) => {
store.push(added);
store.stores.push(added);
};
101 changes: 3 additions & 98 deletions core/loader/src/story-store-data.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,6 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/camelcase */
import { StoriesStore, Story } from '@component-controls/specification';
const deepMerge = require('deepmerge');
import { toId, storyNameFromExport } from '@storybook/csf';
const injectedStories = '__STORIES_HASH__INJECTED_STORIES__';

let storyStore: StoriesStore | undefined = undefined;
const getInjectedStore = (): string | undefined =>
injectedStories.startsWith('__') ? undefined : injectedStories;

const loadStoryStore = (): StoriesStore | undefined => {
if (storyStore) {
return storyStore;
}
if (injectedStories) {
try {
const stores: StoriesStore[] = JSON.parse(injectedStories);

if (stores) {
const globalStore: StoriesStore = {
kinds: {},
stories: {},
components: {},
};
stores.forEach(store => {
if (Object.keys(store.kinds).length > 0) {
Object.keys(store.kinds).forEach(kindName => {
const kind = store.kinds[kindName];

if (kind.moduleId && __webpack_require__) {
try {
// './src/stories/smart-prop-type.stories.js'
const exports = __webpack_require__(kind.moduleId);
Object.keys(exports).forEach(key => {
const exported = exports[key];
if (exported) {
if (key === 'default') {
const { storySource, ...rest } = exported;
Object.assign(kind, rest);
} else {
const story = store.stories[key];
if (story) {
story.renderFn = exported;
if (exported.story) {
Object.assign(story, exported.story);
}
}
}
}
});
} catch (e) {
console.error(`unable to load module ${kind.moduleId}`, e);
}
// clean-up
delete kind.moduleId;
}
globalStore.kinds[kindName] = kind;
Object.keys(store.stories).forEach(storyName => {
const story: Story = store.stories[storyName];
const {
title,
stories,
source,
component,
fileName,
repository,
components,
excludeStories,
includeStories,
...rest
} = kind;
Object.assign(story, deepMerge(rest, story));
if (kind.title && story.name) {
const id = toId(kind.title, storyNameFromExport(story.name));
if (!kind.stories) {
kind.stories = [];
}
kind.stories.push(id);
globalStore.stories[id] = {
...story,
name: storyNameFromExport(story.name),
id,
kind: kind.title,
};
}
});
Object.keys(store.components).forEach(key => {
globalStore.components[key] = store.components[key];
});
});
}
});
storyStore = globalStore;
}
} catch (e) {
console.error(e);
}
}
return storyStore;
};

export default loadStoryStore;
export default getInjectedStore;
2 changes: 1 addition & 1 deletion core/loader/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"outDir": "dist",
"rootDir": "src",
"declaration": true,
"types": ["node", "jest", "webpack-env"],
"types": ["node", "jest"],
"typeRoots": ["../../node_modules/@types", "node_modules/@types"]
},
"include": ["src/**/*", "src/typings.d.ts", "test"],
Expand Down
17 changes: 14 additions & 3 deletions core/specification/src/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,14 @@ export type StoryArguments = StoryArgument[];
export interface StoryParameters {
[name: string]: any;
}

/**
* story render function
*
*/
export type StoryRenderFn = (
controlValues: { [key: string]: any },
context?: any,
) => any;
/**
* Story interface - usually extracted by the AST instrumenting loader
*/
Expand All @@ -83,7 +90,7 @@ export interface Story {
/**
* render function for the story
*/
renderFn?: (controlValues: { [key: string]: any }, context?: any) => any;
renderFn?: StoryRenderFn;
/**
* arguments pass to a CSF story
* eg `export const story = props => <Story {...props} />;`
Expand Down Expand Up @@ -213,9 +220,13 @@ export interface StoriesKind {
}

/**
* store of stories information in memory afte the loader is applied
* store of stories information in memory after the loader is applied
*/
export interface StoriesStore {
/**
* unique has for a store
*/
hash?: string;
kinds: {
[title: string]: StoriesKind;
};
Expand Down
1 change: 1 addition & 0 deletions core/store/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
21 changes: 21 additions & 0 deletions core/store/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2020 Atanas Stoyanov

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:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

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.
53 changes: 53 additions & 0 deletions core/store/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "@component-controls/store",
"version": "0.6.0",
"description": "Component controls shared storage store",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"typings": "dist/index.d.ts",
"files": [
"dist/",
"package.json",
"README.md"
],
"scripts": {
"build": "yarn cross-env NODE_ENV=production rollup -c",
"dev": "yarn cross-env NODE_ENV=development rollup -cw",
"docs": "ts-node -O '{\"module\": \"commonjs\"}' ../../scripts/docs.ts",
"fix": "yarn lint --fix",
"lint": "yarn eslint . --ext mdx,ts,tsx",
"prepare": "yarn build",
"test": "yarn jest"
},
"homepage": "https://github.com/ccontrols/component-controls",
"bugs": {
"url": "https://github.com/ccontrols/component-controls/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/ccontrols/component-controls.git",
"directory": "core/store"
},
"license": "MIT",
"dependencies": {
"@component-controls/loader": "^0.6.0",
"@component-controls/specification": "^0.6.0",
"@storybook/csf": "^0.0.1",
"broadcast-channel": "^3.1.0",
"deepmerge": "^4.2.2",
"typescript": "^3.8.3"
},
"devDependencies": {
"@types/jest": "^25.1.2",
"@types/webpack-env": "^1.15.1",
"cross-env": "^5.2.1",
"eslint": "^6.5.1",
"jest": "^24.9.0"
},
"publishConfig": {
"access": "public"
},
"authors": [
"Atanas Stoyanov"
]
}
5 changes: 5 additions & 0 deletions core/store/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { config } from '../../rollup-config';

export default config({
input: './src/index.ts',
});
Loading

0 comments on commit 69f5762

Please sign in to comment.