@learnpack/learnpack 5.0.341 → 5.0.342

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.
@@ -0,0 +1,48 @@
1
+ -- Lua script to redo the last undone change
2
+ -- Implements Memento pattern with optimistic locking
3
+ --
4
+ -- KEYS[1]: undo:{course}:{exercise}:{lang}
5
+ -- KEYS[2]: redo:{course}:{exercise}:{lang}
6
+ -- KEYS[3]: undo:{course}:{exercise}:{lang}:version
7
+ -- ARGV[1]: current_state_json (state before redo, to save in undo)
8
+ -- ARGV[2]: version_id (current client version for optimistic locking)
9
+ -- ARGV[3]: ttl (432000 seconds = 5 days)
10
+
11
+ -- Get current version
12
+ local current_version = redis.call('GET', KEYS[3])
13
+
14
+ -- Verify version (optimistic locking)
15
+ if current_version ~= false and current_version ~= ARGV[2] then
16
+ return {err = 'VERSION_CONFLICT'}
17
+ end
18
+
19
+ -- Verify there are states to redo
20
+ local redo_length = redis.call('LLEN', KEYS[2])
21
+ if redo_length == 0 then
22
+ return {err = 'NO_REDO_AVAILABLE'}
23
+ end
24
+
25
+ -- Get future state (the most recent in redo stack)
26
+ local future_state = redis.call('LPOP', KEYS[2])
27
+
28
+ if not future_state then
29
+ return {err = 'NO_FUTURE_STATE'}
30
+ end
31
+
32
+ -- Save current state in undo stack
33
+ redis.call('LPUSH', KEYS[1], ARGV[1])
34
+
35
+ -- Maintain state limit in undo (last 5)
36
+ redis.call('LTRIM', KEYS[1], 0, 4)
37
+
38
+ -- Renew TTL of both stacks
39
+ redis.call('EXPIRE', KEYS[1], tonumber(ARGV[3]))
40
+ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[3]))
41
+
42
+ -- Increment version and renew its TTL
43
+ local new_version = redis.call('INCR', KEYS[3])
44
+ redis.call('EXPIRE', KEYS[3], tonumber(ARGV[3]))
45
+
46
+ -- Return array [newVersion, futureState] for compatibility with Redis client
47
+ return {tostring(new_version), future_state}
48
+
@@ -0,0 +1,40 @@
1
+ -- Lua script to save a new state in history
2
+ -- Implements Memento pattern with optimistic locking
3
+ -- NOTE: We save the state BEFORE changes, so users can undo to it
4
+ --
5
+ -- KEYS[1]: undo:{course}:{exercise}:{lang}
6
+ -- KEYS[2]: redo:{course}:{exercise}:{lang}
7
+ -- KEYS[3]: undo:{course}:{exercise}:{lang}:version
8
+ -- ARGV[1]: state_json (complete README BEFORE changes - serialized)
9
+ -- ARGV[2]: version_id (current client version for optimistic locking)
10
+ -- ARGV[3]: ttl (432000 seconds = 5 days)
11
+ -- ARGV[4]: limit (5 states maximum)
12
+
13
+ -- Get current version
14
+ local current_version = redis.call('GET', KEYS[3])
15
+
16
+ -- Verify version (optimistic locking)
17
+ -- If the sent version doesn't match the current one, reject
18
+ if current_version ~= false and current_version ~= ARGV[2] then
19
+ return {err = 'VERSION_CONFLICT'}
20
+ end
21
+
22
+ -- Save new state in undo stack (at the beginning)
23
+ redis.call('LPUSH', KEYS[1], ARGV[1])
24
+
25
+ -- Invalidate redo stack (new change invalidates the "alternative future")
26
+ redis.call('DEL', KEYS[2])
27
+
28
+ -- Keep only the last N states (0 to limit-1)
29
+ redis.call('LTRIM', KEYS[1], 0, tonumber(ARGV[4]) - 1)
30
+
31
+ -- Renew TTL of undo stack
32
+ redis.call('EXPIRE', KEYS[1], tonumber(ARGV[3]))
33
+
34
+ -- Increment version and renew its TTL
35
+ local new_version = redis.call('INCR', KEYS[3])
36
+ redis.call('EXPIRE', KEYS[3], tonumber(ARGV[3]))
37
+
38
+ -- Return new version (as string for compatibility with Redis client)
39
+ return tostring(new_version)
40
+
@@ -0,0 +1,50 @@
1
+ -- Lua script to undo the last change
2
+ -- Implements Memento pattern with optimistic locking
3
+ -- NOTE: Stack contains states BEFORE changes, so index 0 is what we want to restore
4
+ --
5
+ -- KEYS[1]: undo:{course}:{exercise}:{lang}
6
+ -- KEYS[2]: redo:{course}:{exercise}:{lang}
7
+ -- KEYS[3]: undo:{course}:{exercise}:{lang}:version
8
+ -- ARGV[1]: current_state_json (current state to save in redo for potential redo)
9
+ -- ARGV[2]: version_id (current client version for optimistic locking)
10
+ -- ARGV[3]: ttl (432000 seconds = 5 days)
11
+
12
+ -- Get current version
13
+ local current_version = redis.call('GET', KEYS[3])
14
+
15
+ -- Verify version (optimistic locking)
16
+ if current_version ~= false and current_version ~= ARGV[2] then
17
+ return {err = 'VERSION_CONFLICT'}
18
+ end
19
+
20
+ -- Verify there are states to undo
21
+ -- We need at least 1 element (the state before the current change)
22
+ local undo_length = redis.call('LLEN', KEYS[1])
23
+ if undo_length < 1 then
24
+ return {err = 'NO_UNDO_AVAILABLE'}
25
+ end
26
+
27
+ -- Get the saved state (index 0 - the state before current changes)
28
+ local previous_state = redis.call('LINDEX', KEYS[1], 0)
29
+
30
+ if not previous_state then
31
+ return {err = 'NO_PREVIOUS_STATE'}
32
+ end
33
+
34
+ -- Move current state to redo stack
35
+ redis.call('LPUSH', KEYS[2], ARGV[1])
36
+
37
+ -- Remove current state from undo stack (index 0)
38
+ redis.call('LPOP', KEYS[1])
39
+
40
+ -- Renew TTL of both stacks
41
+ redis.call('EXPIRE', KEYS[1], tonumber(ARGV[3]))
42
+ redis.call('EXPIRE', KEYS[2], tonumber(ARGV[3]))
43
+
44
+ -- Increment version and renew its TTL
45
+ local new_version = redis.call('INCR', KEYS[3])
46
+ redis.call('EXPIRE', KEYS[3], tonumber(ARGV[3]))
47
+
48
+ -- Return array [newVersion, previousState] for compatibility with Redis client
49
+ return {tostring(new_version), previous_state}
50
+
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@learnpack/learnpack",
3
3
  "description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
4
- "version": "5.0.341",
4
+ "version": "5.0.342",
5
5
  "author": "Alejandro Sanchez @alesanchezr",
6
6
  "contributors": [
7
7
  {
@@ -161,7 +161,7 @@
161
161
  ]
162
162
  },
163
163
  "scripts": {
164
- "copy-assets": "npx cpy src/creatorDist/**/* lib/creatorDist --parents --verbose && npx cpy src/utils/templates/**/* lib/utils/templates --parents --verbose",
164
+ "copy-assets": "npx cpy src/creatorDist/**/* lib/creatorDist --parents --verbose && npx cpy src/utils/templates/**/* lib/utils/templates --parents --verbose && npx cpy src/lua/**/* lib/lua --parents --verbose",
165
165
  "tsc": "tsc -b",
166
166
  "postpack": "rm -f oclif.manifest.json && eslint . --ext .ts --config .eslintrc",
167
167
  "prepack": "rm -rf lib && tsc -b && npm run copy-assets",