@profitlich/template-toolkit 2.8.4 → 2.10.0

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/scripts/deploy.js +103 -67
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@profitlich/template-toolkit",
3
- "version": "2.8.4",
3
+ "version": "2.10.0",
4
4
  "description": "Shared SCSS layout system, JS utilities, components and build scripts for profitlich template repos",
5
5
  "type": "module",
6
6
  "exports": {
package/scripts/deploy.js CHANGED
@@ -24,6 +24,7 @@ async function createClient(accessOptions) {
24
24
  const client = new ftp.Client();
25
25
  client.ftp.verbose = false;
26
26
  await client.access(accessOptions);
27
+ client.ftp.socket.setKeepAlive(true, 10000);
27
28
  return client;
28
29
  }
29
30
 
@@ -38,34 +39,35 @@ export async function runDeploy(mode, uploadTasks, options = {}) {
38
39
  secure: true
39
40
  };
40
41
 
42
+ const mainClient = new ftp.Client();
43
+ mainClient.ftp.verbose = false;
41
44
  let activeProgressBar = null;
42
45
 
43
46
  try {
44
47
  console.log(`šŸš€ Starting deployment for: ${modeUpper}`);
45
48
 
49
+ await mainClient.access(accessOptions);
50
+ mainClient.ftp.socket.setKeepAlive(true, 10000);
51
+
46
52
  for (const task of uploadTasks) {
47
53
  console.log(`\nProcessing Task: ${task.name}`);
48
54
 
49
- const mainClient = new ftp.Client();
50
- mainClient.ftp.verbose = false;
51
-
52
- try {
53
- await mainClient.access(accessOptions);
55
+ const files = await glob(task.localPattern, {
56
+ nodir: true,
57
+ dot: true,
58
+ ignore: task.ignore
59
+ });
54
60
 
55
- const files = await glob(task.localPattern, {
56
- nodir: true,
57
- dot: true,
58
- ignore: task.ignore
59
- });
61
+ if (files.length === 0) {
62
+ console.log('No files found for this task.');
63
+ continue;
64
+ }
60
65
 
61
- if (files.length === 0) {
62
- console.log('No files found for this task.');
63
- continue;
64
- }
66
+ // Determine which files are newer than their remote counterparts
67
+ process.stdout.write(` Checking ${files.length} files...`);
68
+ const filesToUpload = [];
65
69
 
66
- // Determine which files are newer than their remote counterparts
67
- process.stdout.write(` Checking ${files.length} files...`);
68
- const filesToUpload = [];
70
+ if (parallel <= 1) {
69
71
  for (const file of files) {
70
72
  const relativeFile = path.relative(task.localBase, file);
71
73
  const remotePath = path.join(task.remoteDir, relativeFile).replace(/\\/g, '/');
@@ -73,64 +75,96 @@ export async function runDeploy(mode, uploadTasks, options = {}) {
73
75
  filesToUpload.push({ file, remotePath });
74
76
  }
75
77
  }
76
- process.stdout.write(` ${filesToUpload.length} changed.\n`);
78
+ } else {
79
+ const checkWorkerCount = Math.min(parallel, files.length);
80
+ const checkWorkers = await Promise.all(
81
+ Array.from({ length: checkWorkerCount }, () => createClient(accessOptions))
82
+ );
83
+ const checkQueue = [...files];
84
+ await Promise.all(checkWorkers.map(async (workerClient) => {
85
+ try {
86
+ while (true) {
87
+ const file = checkQueue.shift();
88
+ if (!file) break;
89
+ const relativeFile = path.relative(task.localBase, file);
90
+ const remotePath = path.join(task.remoteDir, relativeFile).replace(/\\/g, '/');
91
+ if (await isNewer(workerClient, file, remotePath)) {
92
+ filesToUpload.push({ file, remotePath });
93
+ }
94
+ }
95
+ } finally {
96
+ workerClient.close();
97
+ }
98
+ }));
99
+ }
77
100
 
78
- if (filesToUpload.length === 0) {
79
- console.log(' All files are up to date, skipping.');
80
- continue;
81
- }
101
+ process.stdout.write(` ${filesToUpload.length} changed.\n`);
82
102
 
83
- const progressBar = new cliProgress.SingleBar({
84
- format: ' Upload |{bar}| {percentage}% {value}/{total} files {duration_formatted}',
85
- barCompleteChar: 'ā–ˆ',
86
- barIncompleteChar: 'ā–‘',
87
- hideCursor: true
88
- });
89
-
90
- activeProgressBar = progressBar;
91
- progressBar.start(filesToUpload.length, 0);
92
-
93
- if (parallel <= 1) {
94
- for (const { file, remotePath } of filesToUpload) {
95
- await mainClient.ensureDir(path.dirname(remotePath));
96
- await mainClient.uploadFrom(file, remotePath);
97
- progressBar.increment();
98
- }
99
- } else {
100
- // Pre-create all required remote directories with the main client
101
- const uniqueDirs = [...new Set(filesToUpload.map(({ remotePath }) => path.dirname(remotePath)))];
102
- for (const dir of uniqueDirs) {
103
- await mainClient.ensureDir(dir);
104
- }
103
+ if (filesToUpload.length === 0) {
104
+ console.log(' All files are up to date, skipping.');
105
+ continue;
106
+ }
105
107
 
106
- // Spawn parallel worker connections
107
- const workerCount = Math.min(parallel, filesToUpload.length);
108
- const workers = await Promise.all(
109
- Array.from({ length: workerCount }, () => createClient(accessOptions))
110
- );
108
+ const progressBar = new cliProgress.SingleBar({
109
+ format: ' Upload |{bar}| {percentage}% {value}/{total} files {duration_formatted}',
110
+ barCompleteChar: 'ā–ˆ',
111
+ barIncompleteChar: 'ā–‘',
112
+ hideCursor: true
113
+ });
114
+
115
+ activeProgressBar = progressBar;
116
+ progressBar.start(filesToUpload.length, 0);
117
+
118
+ if (parallel <= 1) {
119
+ for (const { file, remotePath } of filesToUpload) {
120
+ await mainClient.ensureDir(path.dirname(remotePath));
121
+ await mainClient.uploadFrom(file, remotePath);
122
+ progressBar.increment();
123
+ }
124
+ } else {
125
+ // Pre-create all required remote directories with the main client
126
+ const uniqueDirs = [...new Set(filesToUpload.map(({ remotePath }) => path.dirname(remotePath)))];
127
+ for (const dir of uniqueDirs) {
128
+ await mainClient.ensureDir(dir);
129
+ }
111
130
 
112
- const queue = [...filesToUpload];
113
- await Promise.all(workers.map(async (workerClient) => {
114
- try {
131
+ // Spawn parallel worker connections
132
+ const workerCount = Math.min(parallel, filesToUpload.length);
133
+ const workers = await Promise.all(
134
+ Array.from({ length: workerCount }, () => createClient(accessOptions))
135
+ );
136
+
137
+ const queue = [...filesToUpload];
138
+ await Promise.all(workers.map(async (initialWorkerClient) => {
139
+ let workerClient = initialWorkerClient;
140
+ try {
141
+ while (true) {
142
+ const item = queue.shift();
143
+ if (!item) break;
144
+ let retries = 0;
115
145
  while (true) {
116
- const item = queue.shift();
117
- if (!item) break;
118
- await workerClient.uploadFrom(item.file, item.remotePath);
119
- progressBar.increment();
146
+ try {
147
+ await workerClient.uploadFrom(item.file, item.remotePath);
148
+ break;
149
+ } catch (err) {
150
+ retries++;
151
+ workerClient.close();
152
+ if (retries >= 3) throw err;
153
+ await delay(1000 * retries);
154
+ workerClient = await createClient(accessOptions);
155
+ }
120
156
  }
121
- } finally {
122
- workerClient.close();
157
+ progressBar.increment();
123
158
  }
124
- }));
125
- }
126
-
127
- activeProgressBar.stop();
128
- activeProgressBar = null;
129
- await delay(50);
130
-
131
- } finally {
132
- mainClient.close();
159
+ } finally {
160
+ workerClient.close();
161
+ }
162
+ }));
133
163
  }
164
+
165
+ activeProgressBar.stop();
166
+ activeProgressBar = null;
167
+ await delay(50);
134
168
  }
135
169
 
136
170
  console.log('\nāœ… Deployment completed successfully!');
@@ -140,6 +174,8 @@ export async function runDeploy(mode, uploadTasks, options = {}) {
140
174
  activeProgressBar.stop();
141
175
  }
142
176
  console.error('Deployment failed:', err);
177
+ } finally {
178
+ mainClient.close();
143
179
  }
144
180
  }
145
181