@fugood/bricks-project 2.21.0-beta.14.test5 → 2.21.0-beta.14.test7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -1,10 +1,5 @@
1
1
  export type * from './types'
2
2
 
3
- import type { DataLink, Data } from './types'
4
-
5
- export { makeId } from './uuid'
6
-
7
- export const linkData: ((dataGetter: () => Data) => DataLink) = (dataGetter) => ({
8
- __typename: 'DataLink',
9
- data: dataGetter,
10
- })
3
+ export { makeId } from './utils/id'
4
+ export { generateDataCalculationMapEditorInfo } from './utils/calc'
5
+ export { linkData, useSystemData } from './utils/data'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fugood/bricks-project",
3
- "version": "2.21.0-beta.14.test5",
3
+ "version": "2.21.0-beta.14.test7",
4
4
  "main": "index.ts",
5
5
  "scripts": {
6
6
  "build": "node scripts/build.js"
@@ -0,0 +1,24 @@
1
+ import { $ } from 'bun'
2
+ import { deployApp, deployModule } from '../api'
3
+
4
+ const cwd = process.cwd()
5
+
6
+ const unstagedChanges = await $`cd ${cwd} && git diff --name-only --diff-filter=ACMR`.text()
7
+ if (unstagedChanges) throw new Error('Unstaged changes found, please commit or stash your changes before deploying')
8
+
9
+ const commitId = (await $`cd ${cwd} && git rev-parse HEAD`.text()).trim()
10
+ const app = await Bun.file(`${cwd}/application.json`).json()
11
+ const stage = app.stage || 'production'
12
+ const config = await Bun.file(`${cwd}/.bricks/build/application-config.json`).json()
13
+
14
+ // ask for confirmation
15
+ const confirm = prompt('Are you sure you want to deploy? (y/n)')
16
+ if (confirm !== 'y') throw new Error('Deployment cancelled')
17
+
18
+ if (!app.type || app.type === 'application') {
19
+ await deployApp(stage, app.id, config, commitId)
20
+ console.log('App deployed')
21
+ } else if (app.type === 'module') {
22
+ await deployModule(stage, app.id, config, commitId)
23
+ console.log('Module deployed')
24
+ }
@@ -0,0 +1,12 @@
1
+ import { $ } from 'bun'
2
+
3
+ const cwd = process.cwd()
4
+
5
+ const libFiles = ['types', 'utils', 'index.ts']
6
+
7
+ await $`mkdir -p ${cwd}/project`
8
+ for (const file of libFiles) {
9
+ await $`cp -r ${__dirname}/../${file} ${cwd}/project`
10
+ }
11
+
12
+ console.log('Copied files to project/')
@@ -1,15 +1,18 @@
1
+ // eslint-disable-next-line import/no-extraneous-dependencies
1
2
  import { app, BrowserWindow } from 'electron'
2
3
  import { readFile } from 'fs/promises'
3
4
  import { watchFile } from 'fs'
4
5
 
5
- let config = JSON.parse(await readFile(process.cwd() + '/.bricks/build/application-config.json'))
6
+ const cwd = process.cwd()
7
+
8
+ let config = JSON.parse(await readFile(`${cwd}/.bricks/build/application-config.json`))
6
9
 
7
10
  const stage = process.env.BRICKS_STAGE || 'production'
8
11
 
9
12
  const previewUrlMap = {
10
13
  production: 'https://control.bricks.tools/applicationPreview.html',
11
14
  beta: 'https://control-beta.bricks.tools/applicationPreview.html',
12
- dev: 'http://localhost:3006/dev-applicationPreview.html',
15
+ development: 'http://localhost:3006/dev-applicationPreview.html',
13
16
  }
14
17
 
15
18
  const previewUrl = previewUrlMap[stage]
@@ -33,7 +36,7 @@ app.on('ready', () => {
33
36
  mainWindow.webContents.once('dom-ready', sendConfig)
34
37
 
35
38
  watchFile(
36
- process.cwd() + '/.bricks/build/application-config.json',
39
+ `${cwd}/.bricks/build/application-config.json`,
37
40
  {
38
41
  bigint: false,
39
42
  persistent: true,
@@ -41,7 +44,7 @@ app.on('ready', () => {
41
44
  },
42
45
  async () => {
43
46
  console.log('Detected config changed')
44
- config = JSON.parse(await readFile(process.cwd() + '/.bricks/build/application-config.json'))
47
+ config = JSON.parse(await readFile(`${cwd}/.bricks/build/application-config.json`))
45
48
  sendConfig()
46
49
  },
47
50
  )
package/tools/preview.ts CHANGED
@@ -1,20 +1,37 @@
1
- import { $, main } from 'bun'
2
- import { watch, readFile } from 'fs'
1
+ import { $ } from 'bun'
2
+ import { watch } from 'fs'
3
+ import { parseArgs } from 'util'
3
4
  import { debounce } from 'lodash'
4
5
 
5
- const app = await Bun.file(process.cwd() + '/application.json').json()
6
+ const { values } = parseArgs({
7
+ args: Bun.argv,
8
+ options: {
9
+ 'skip-typecheck': {
10
+ type: 'boolean',
11
+ },
12
+ },
13
+ strict: true,
14
+ allowPositionals: true,
15
+ })
16
+
17
+ const useTypecheck = !values['skip-typecheck']
6
18
 
7
- const compile = debounce(async () => {
19
+ const compile = async () => {
20
+ if (useTypecheck) await $`bun typecheck`
8
21
  await $`bun compile`
9
- }, 500)
10
-
11
- watch(
12
- process.cwd() + '/subspaces',
13
- { recursive: true },
14
- async (event, filename) => {
15
- console.log(`Detected ${event} in ${filename}`)
16
- compile()
17
- },
18
- )
22
+ }
23
+
24
+ await compile()
25
+
26
+ const compileDebounced = debounce(compile, 500)
27
+
28
+ const cwd = process.cwd()
29
+
30
+ watch(`${cwd}/subspaces`, { recursive: true }, async (event, filename) => {
31
+ console.log(`Detected ${event} in ${filename}`)
32
+ compileDebounced()
33
+ })
34
+
35
+ const app = await Bun.file(`${cwd}/application.json`).json()
19
36
 
20
37
  await $`BRICKS_STAGE=${app.stage || 'production'} bunx electron ${__dirname}/preview-main.mjs`
package/tools/pull.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { $ } from 'bun'
2
+ import { format } from 'prettier'
3
+ import { pullApplicationProject, pullModuleProject } from '../api'
4
+
5
+ const cwd = process.cwd()
6
+
7
+ const unstagedChanges = await $`cd ${cwd} && git diff --name-only --diff-filter=ACMR`.text()
8
+ if (unstagedChanges)
9
+ throw new Error('Unstaged changes found, please commit or stash your changes before deploying')
10
+
11
+ const app = await Bun.file(`${cwd}/application.json`).json()
12
+ const stage = app.stage || 'production'
13
+ const { files, lastCommitId } =
14
+ app.type === 'module'
15
+ ? await pullModuleProject(stage, app.id)
16
+ : await pullApplicationProject(stage, app.id)
17
+
18
+ const found = (await $`cd ${cwd} && git rev-list -1 ${lastCommitId}`.nothrow().text())
19
+ .trim()
20
+ .match(/^[a-f0-9]{40}$/)
21
+
22
+ const commitId = (await $`cd ${cwd} && git rev-parse HEAD`.text()).trim()
23
+
24
+ if (commitId === lastCommitId) throw new Error('Commit not changed')
25
+
26
+ const branchName = 'BRICKS_PROJECT_try-pull-application'
27
+
28
+ await $`cd ${cwd} && git branch -D ${branchName}`.nothrow()
29
+
30
+ let useMain = false
31
+ if (found) {
32
+ await $`cd ${cwd} && git checkout -b ${branchName} ${lastCommitId}`.nothrow()
33
+ } else {
34
+ await $`cd ${cwd} && git checkout -b ${branchName}`
35
+ useMain = true
36
+ }
37
+
38
+ await Promise.all(
39
+ files.map(async (file) =>
40
+ Bun.write(
41
+ `${cwd}/${file.name}`,
42
+ file.formatable ? await format(file.input, { parser: 'typescript' }) : file.input,
43
+ ),
44
+ ),
45
+ )
46
+
47
+ await $`cd ${cwd} && git add .`
48
+ await $`cd ${cwd} && git commit -m 'Apply ${app.name} file changes'`
49
+ if (!useMain) {
50
+ await $`cd ${cwd} && git merge main`
51
+ }
package/types/common.ts CHANGED
@@ -12,7 +12,7 @@ export interface Brick {
12
12
  events: {}
13
13
  outlets?: {}
14
14
  animation?: {}
15
- switches: Array<SwitchDef>
15
+ switches?: Array<SwitchDef>
16
16
  }
17
17
 
18
18
  export enum LocalSyncStrategy {
@@ -30,7 +30,7 @@ export interface Generator {
30
30
  property?: {}
31
31
  events: {}
32
32
  outlets?: {}
33
- switches: Array<SwitchDef>
33
+ switches?: Array<SwitchDef>
34
34
  }
35
35
 
36
36
  export type SubspaceID = string
@@ -103,7 +103,7 @@ export type ApplicationSettings = {
103
103
  borderBottomLeftRadius?: number
104
104
  borderBottomRightRadius?: number
105
105
  }
106
- },
106
+ }
107
107
  }
108
108
 
109
109
  export type Application = {
package/types/switch.ts CHANGED
@@ -36,10 +36,13 @@ export interface SwitchDef {
36
36
  animation?: {}
37
37
  conds?: Array<{
38
38
  method: '==' | '!=' | '>' | '<' | '>=' | '<='
39
- cond: SwitchCondInnerStateCurrentCanvas | SwitchCondData | {
40
- __typename: 'SwitchCondInnerStateOutlet'
41
- outlet: string
42
- value: any
43
- }
39
+ cond:
40
+ | SwitchCondInnerStateCurrentCanvas
41
+ | SwitchCondData
42
+ | {
43
+ __typename: 'SwitchCondInnerStateOutlet'
44
+ outlet: string
45
+ value: any
46
+ }
44
47
  }>
45
48
  }
package/utils/calc.ts ADDED
@@ -0,0 +1,118 @@
1
+ import type { DataCalculationMap, DataCalculationData, DataCommand } from '../types/data-calc'
2
+
3
+ const GRID = {
4
+ WIDTH: 300, // Distance between columns
5
+ HEIGHT: 150, // Distance between rows
6
+ PADDING: 15, // Edge padding
7
+ COLUMNS: 4, // Max columns in grid
8
+ ROWS: 3, // Max rows in grid
9
+ }
10
+
11
+ // TODO: Improve the algorithm to minimize crossing lines
12
+
13
+ // If we are too lazy to describe nodes in the editing interface,
14
+ // we can let it generate it automatically
15
+ export const generateDataCalculationMapEditorInfo = (
16
+ nodes: Array<DataCalculationData | DataCommand>,
17
+ ) => {
18
+ const editorInfo: DataCalculationMap['editorInfo'] = []
19
+
20
+ // Track node relationships
21
+ const inputCounts = new Map<DataCalculationData | DataCommand, number>()
22
+ const outputCounts = new Map<DataCalculationData | DataCommand, number>()
23
+ const connectedTo = new Map<
24
+ DataCalculationData | DataCommand,
25
+ Set<DataCalculationData | DataCommand>
26
+ >()
27
+
28
+ // Analyze node connections
29
+ nodes.forEach((node) => {
30
+ // Count and track inputs
31
+ if ('inputs' in node) {
32
+ const inputs = node.inputs
33
+ .filter((input) => input !== null)
34
+ .map((input) => (Array.isArray(input) ? input.length : 1))
35
+ .reduce((sum, count) => sum + count, 0)
36
+ inputCounts.set(node, inputs)
37
+
38
+ // Track connections
39
+ node.inputs.forEach((input) => {
40
+ if (Array.isArray(input)) {
41
+ input.forEach((conn) => {
42
+ if (!connectedTo.has(node)) {
43
+ connectedTo.set(node, new Set())
44
+ }
45
+ const sourceNode = nodes.find((n) => 'id' in n && n.id === conn.id)
46
+ if (sourceNode) {
47
+ connectedTo.get(node)!.add(sourceNode)
48
+ }
49
+ })
50
+ }
51
+ })
52
+ } else {
53
+ inputCounts.set(node, 0)
54
+ }
55
+
56
+ // Count outputs
57
+ if ('outputs' in node) {
58
+ const outputs = node.outputs
59
+ .filter((output) => output !== null)
60
+ .map((output) => (Array.isArray(output) ? output.length : 1))
61
+ .reduce((sum, count) => sum + count, 0)
62
+ outputCounts.set(node, outputs)
63
+ } else {
64
+ outputCounts.set(node, 0)
65
+ }
66
+ })
67
+
68
+ // Calculate layers
69
+ const layers: Array<Array<DataCalculationData | DataCommand>> = [[], [], [], []]
70
+
71
+ nodes.forEach((node) => {
72
+ const inputs = inputCounts.get(node) || 0
73
+ const outputs = outputCounts.get(node) || 0
74
+ const connections = connectedTo.get(node)?.size || 0
75
+
76
+ if (inputs === 0) {
77
+ // Input nodes (leftmost)
78
+ layers[0].push(node)
79
+ } else if (outputs === 0) {
80
+ // Output nodes (rightmost)
81
+ layers[3].push(node)
82
+ } else if (connections > 1) {
83
+ // Nodes with multiple connections (middle-right)
84
+ layers[2].push(node)
85
+ } else {
86
+ // Processing nodes (middle-left)
87
+ layers[1].push(node)
88
+ }
89
+ })
90
+
91
+ // Position nodes in each layer
92
+ layers.forEach((layerNodes, layerIndex) => {
93
+ // Sort nodes by their connections to try to minimize crossing lines
94
+ layerNodes.sort((a, b) => {
95
+ const aConns = connectedTo.get(a)?.size || 0
96
+ const bConns = connectedTo.get(b)?.size || 0
97
+ return bConns - aConns
98
+ })
99
+
100
+ // Position nodes in the layer
101
+ layerNodes.forEach((node, nodeIndex) => {
102
+ // Distribute nodes evenly within their layer
103
+ const row = nodeIndex % GRID.ROWS
104
+ const offset = Math.floor(nodeIndex / GRID.ROWS) * (GRID.HEIGHT / 2)
105
+
106
+ editorInfo.push({
107
+ node,
108
+ position: {
109
+ x: GRID.PADDING + layerIndex * GRID.WIDTH,
110
+ y: GRID.PADDING + row * GRID.HEIGHT + offset,
111
+ },
112
+ points: [],
113
+ })
114
+ })
115
+ })
116
+
117
+ return editorInfo
118
+ }