Skip to content

Commit

Permalink
Merge pull request #385 from permaweb/jfrain99/ldocs
Browse files Browse the repository at this point in the history
feat(aos): add ldocs to process lua
  • Loading branch information
twilson63 authored Nov 1, 2024
2 parents 958aeeb + e136adc commit 3ac0aae
Show file tree
Hide file tree
Showing 27 changed files with 4,415 additions and 88 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,22 @@ jobs:
path: ${{ steps.aos_llama_module.outputs.aos_module_path }}
retention-days: 10

# Set up Lua
- name: 🔧 Set up Lua
uses: leafo/gh-actions-lua@v10
with:
luaVersion: 5.3

# Install LDoc
- name: 📦 Install LDoc
run: |
luarocks install ldoc
# Build process docs
- name: 📄 Build Process Docs
run: |
yarn build-docs
# TODO: update manifests with new version and txids

# - name: ⬆️ Push
Expand Down
6 changes: 6 additions & 0 deletions config.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
file = {"./process", exclude = {"./process/node_modules", "./process/crypto", "./process/test", "./process/dump.lua", "./process/base64.lua", "./process/bint.lua" } }
project = "AOS"
dir = "process/docs/"
description = [[
AOS is your personal operating system for the ao computer.
]]
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"scripts": {
"start": "node src/index.js",
"test": "node --test test",
"build-docs": "rm -rf process/docs && ldoc .",
"generate-wallet": "node -e \"require('arweave').init({}).wallets.generate().then(JSON.stringify).then(console.log.bind(console))\" > wallet.json",
"deploy": "npx -y [email protected] upload-file --turbo --local-path=./$(npm pack) -w ~/.wallet.json -F 0d009773-ce2c-4539-8e0d-c331db9ab348 | jq .created[0].dataTxId"
},
Expand Down
116 changes: 113 additions & 3 deletions process/ao.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
--- The AO module provides functionality for managing the AO environment and handling messages. Returns the ao table.
-- @module ao

local oldao = ao or {}

--- The AO module
-- @table ao
-- @field _version The version number of the ao module
-- @field _module The module id of the process
-- @field id The id of the process
-- @field authorities A table of authorities of the process
-- @field reference The reference number of the process
-- @field outbox The outbox of the process
-- @field nonExtractableTags The non-extractable tags
-- @field nonForwardableTags The non-forwardable tags
-- @field clone The clone function
-- @field normalize The normalize function
-- @field sanitize The sanitize function
-- @field init The init function
-- @field log The log function
-- @field clearOutbox The clearOutbox function
-- @field send The send function
-- @field spawn The spawn function
-- @field assign The assign function
-- @field isTrusted The isTrusted function
-- @field result The result function
local ao = {
_version = "0.0.6",
id = oldao.id or "",
Expand All @@ -20,6 +45,10 @@ local ao = {
}
}

--- Checks if a key exists in a list.
-- @lfunction _includes
-- @tparam {table} list The list to check against
-- @treturn {function} A function that takes a key and returns true if the key exists in the list
local function _includes(list)
return function(key)
local exists = false
Expand All @@ -34,6 +63,10 @@ local function _includes(list)
end
end

--- Checks if a table is an array.
-- @lfunction isArray
-- @tparam {table} table The table to check
-- @treturn {boolean} True if the table is an array, false otherwise
local function isArray(table)
if type(table) == "table" then
local maxIndex = 0
Expand All @@ -49,8 +82,17 @@ local function isArray(table)
return false
end

--- Pads a number with leading zeros to 32 digits.
-- @lfunction padZero32
-- @tparam {number} num The number to pad
-- @treturn {string} The padded number as a string
local function padZero32(num) return string.format("%032d", num) end

--- Clones a table recursively.
-- @function clone
-- @tparam {any} obj The object to clone
-- @tparam {table} seen The table of seen objects (default is nil)
-- @treturn {any} The cloned object
function ao.clone(obj, seen)
-- Handle non-tables and previously-seen tables.
if type(obj) ~= 'table' then return obj end
Expand All @@ -64,6 +106,10 @@ function ao.clone(obj, seen)
return setmetatable(res, getmetatable(obj))
end

--- Normalizes a message by extracting tags.
-- @function normalize
-- @tparam {table} msg The message to normalize
-- @treturn {table} The normalized message
function ao.normalize(msg)
for _, o in ipairs(msg.Tags) do
if not _includes(ao.nonExtractableTags)(o.name) then
Expand All @@ -73,6 +119,10 @@ function ao.normalize(msg)
return msg
end

--- Sanitizes a message by removing non-forwardable tags.
-- @function sanitize
-- @tparam {table} msg The message to sanitize
-- @treturn {table} The sanitized message
function ao.sanitize(msg)
local newMsg = ao.clone(msg)

Expand All @@ -83,6 +133,9 @@ function ao.sanitize(msg)
return newMsg
end

--- Initializes the AO environment, including ID, module, authorities, outbox, and environment.
-- @function init
-- @tparam {table} env The environment object
function ao.init(env)
if ao.id == "" then ao.id = env.Process.Id end

Expand All @@ -105,18 +158,25 @@ function ao.init(env)

end

--- Logs a message to the output.
-- @function log
-- @tparam {string} txt The message to log
function ao.log(txt)
if type(ao.outbox.Output) == 'string' then
ao.outbox.Output = {ao.outbox.Output}
end
table.insert(ao.outbox.Output, txt)
end

-- clears outbox
--- Clears the outbox.
-- @function clearOutbox
function ao.clearOutbox()
ao.outbox = {Output = {}, Messages = {}, Spawns = {}, Assignments = {}}
end

--- Sends a message.
-- @function send
-- @tparam {table} msg The message to send
function ao.send(msg)
assert(type(msg) == 'table', 'msg should be a table')
ao.reference = ao.reference + 1
Expand Down Expand Up @@ -191,6 +251,10 @@ function ao.send(msg)
return message
end

--- Spawns a process.
-- @function spawn
-- @tparam {string} module The module source id
-- @tparam {table} msg The message to send
function ao.spawn(module, msg)
assert(type(module) == "string", "Module source id is required!")
assert(type(msg) == 'table', 'Message must be a table')
Expand Down Expand Up @@ -263,15 +327,21 @@ function ao.spawn(module, msg)
return spawn
end

--- Assigns a message to a process.
-- @function assign
-- @tparam {table} assignment The assignment to assign
function ao.assign(assignment)
assert(type(assignment) == 'table', 'assignment should be a table')
assert(type(assignment.Processes) == 'table', 'Processes should be a table')
assert(type(assignment.Message) == "string", "Message should be a string")
table.insert(ao.outbox.Assignments, assignment)
end

-- The default security model of AOS processes: Trust all and *only* those
-- on the ao.authorities list.
--- Checks if a message is trusted.
-- The default security model of AOS processes: Trust all and *only* those on the ao.authorities list.
-- @function isTrusted
-- @tparam {table} msg The message to check
-- @treturn {boolean} True if the message is trusted, false otherwise
function ao.isTrusted(msg)
for _, authority in ipairs(ao.authorities) do
if msg.From == authority then return true end
Expand All @@ -280,6 +350,10 @@ function ao.isTrusted(msg)
return false
end

--- Returns the result of the process.
-- @function result
-- @tparam {table} result The result of the process
-- @treturn {table} The result of the process, including Output, Messages, Spawns, and Assignments
function ao.result(result)
-- if error then only send the Error to CU
if ao.outbox.Error or result.Error then
Expand All @@ -293,4 +367,40 @@ function ao.result(result)
}
end


--- Add the MatchSpec to the ao.assignables table. A optional name may be provided.
-- This implies that ao.assignables may have both number and string indices.
-- Added in the assignment module.
-- @function addAssignable
-- @tparam ?string|number|any nameOrMatchSpec The name of the MatchSpec
-- to be added to ao.assignables. if a MatchSpec is provided, then
-- no name is included
-- @tparam ?any matchSpec The MatchSpec to be added to ao.assignables. Only provided
-- if its name is passed as the first parameter
-- @treturn ?string|number name The name of the MatchSpec, either as provided
-- as an argument or as incremented
-- @see assignment

--- Remove the MatchSpec, either by name or by index
-- If the name is not found, or if the index does not exist, then do nothing.
-- Added in the assignment module.
-- @function removeAssignable
-- @tparam {string|number} name The name or index of the MatchSpec to be removed
-- @see assignment

--- Return whether the msg is an assignment or not. This can be determined by simply check whether the msg's Target is this process' id
-- Added in the assignment module.
-- @function isAssignment
-- @param msg The msg to be checked
-- @treturn boolean isAssignment
-- @see assignment

--- Check whether the msg matches any assignable MatchSpec.
-- If not assignables are configured, the msg is deemed not assignable, by default.
-- Added in the assignment module.
-- @function isAssignable
-- @param msg The msg to be checked
-- @treturn boolean isAssignable
-- @see assignment

return ao
47 changes: 20 additions & 27 deletions process/assignment.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
--- The Assignment module provides functionality for handling assignments. Returns the Assignment table.
-- @module assignment

--- The Assignment module
-- @table Assignment
-- @field _version The version number of the assignment module
-- @field init The init function
local Assignment = { _version = "0.1.0" }
local utils = require('.utils')

-- Implement assignable polyfills on _ao
--- Implement assignable polyfills on ao.
-- Creates addAssignable, removeAssignable, isAssignment, and isAssignable fields on ao.
-- @function init
-- @tparam {table} ao The ao environment object
-- @see ao.addAssignable
-- @see ao.removeAssignable
-- @see ao.isAssignment
-- @see ao.isAssignable
function Assignment.init (ao)
-- Find the index of an object in an array by a given property
-- @lfunction findIndexByProp
-- @tparam {table} array The array to search
-- @tparam {string} prop The property to search by
-- @tparam {any} value The value to search for
-- @treturn {number|nil} The index of the object, or nil if not found
local function findIndexByProp(array, prop, value)
for index, object in ipairs(array) do
if object[prop] == value then return index end
Expand All @@ -14,16 +33,6 @@ function Assignment.init (ao)

ao.assignables = ao.assignables or {}

-- Add the MatchSpec to the ao.assignables table. A optional name may be provided.
-- This implies that ao.assignables may have both number and string indices.
--
-- @tparam ?string|number|any nameOrMatchSpec The name of the MatchSpec
-- to be added to ao.assignables. if a MatchSpec is provided, then
-- no name is included
-- @tparam ?any matchSpec The MatchSpec to be added to ao.assignables. Only provided
-- if its name is passed as the first parameter
-- @treturn ?string|number name The name of the MatchSpec, either as provided
-- as an argument or as incremented
ao.addAssignable = ao.addAssignable or function (...)
local name = nil
local matchSpec = nil
Expand All @@ -50,11 +59,6 @@ function Assignment.init (ao)
end
end

-- Remove the MatchSpec, either by name or by index
-- If the name is not found, or if the index does not exist, then do nothing.
--
-- @tparam string|number name The name or index of the MatchSpec to be removed
-- @treturn nil nil
ao.removeAssignable = ao.removeAssignable or function (name)
local idx = nil

Expand All @@ -69,19 +73,8 @@ function Assignment.init (ao)
table.remove(ao.assignables, idx)
end

-- Return whether the msg is an assignment or not. This
-- can be determined by simply check whether the msg's Target is
-- This process' id
--
-- @param msg The msg to be checked
-- @treturn boolean isAssignment
ao.isAssignment = ao.isAssignment or function (msg) return msg.Target ~= ao.id end

-- Check whether the msg matches any assignable MatchSpec.
-- If not assignables are configured, the msg is deemed not assignable, by default.
--
-- @param msg The msg to be checked
-- @treturn boolean isAssignable
ao.isAssignable = ao.isAssignable or function (msg)
for _, assignable in pairs(ao.assignables) do
if utils.matchesSpec(msg, assignable.pattern) then return true end
Expand Down
12 changes: 11 additions & 1 deletion process/boot.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
--- The Boot module provides functionality for booting the process. Returns the boot function.
-- @module boot

-- This is for aop6 Boot Loader
-- See: https://github.com/permaweb/aos/issues/342
-- For the Process as the first Message, if On-Boot
Expand All @@ -18,6 +21,13 @@ function drive.getData(txId)
return contents
end

--- The boot function.
-- If the message has no On-Boot tag, do nothing.
-- If the message has an On-Boot tag with the value 'Data', then evaluate the message.
-- If the message has an On-Boot tag with a tx id, then download and evaluate the tx data.
-- @function boot
-- @param ao The ao environment object
-- @see eval
return function (ao)
local eval = require(".eval")(ao)
return function (msg)
Expand All @@ -30,5 +40,5 @@ return function (ao)
local loadedVal = drive.getData(msg.Tags['On-Boot'])
eval({ Data = loadedVal })
end
end
end
end
Loading

0 comments on commit 3ac0aae

Please sign in to comment.